Слово "mixins" переводится как "примеси", но в тексте я его, пожалуй, оставлю без перевода – прим. пер.
Mixins – это программные конструкции, которые позволяют подмешивать сгенерированный во время компиляции код внутрь основного исходного кода. Mixins могут быть следующих типов:
В D имеется возможность вставлять код в виде строки, если эта строка известна во время компиляции. Синтаксис строковых mixins показан ниже:
mixin (генерируемая_во_время_компиляции_строка)
Ниже приведен простой пример для строковых mixins.
import std.stdio; void main() { mixin(`writeln("Привет, мир!");`); }
Когда вы скомпилируете и выполните эту программу, она возвратит следующий результат:
Привет, мир!
Вот еще один пример, в котором мы передаём строку во время компиляции, чтобы mixins могли использовать функции для повторного использования кода.
import std.stdio; string print(string s) { return `writeln("` ~ s ~ `");`; } void main() { mixin (print("str1")); mixin (print("str2")); }
Когда вы скомпилируете и выполните эту программу, она возвратит следующий результат:
str1 str2
Шаблоны в D определяют шаблоны обобщённого кода, чтобы компилятор мог генерировать из них фактические экземпляры. Шаблоны могут генерировать функции, структуры, объединения, классы, интерфейсы и любой другой допустимый код на D. Синтаксис шаблонов mixins показан ниже.
mixin имя_шаблона!(параметры_шаблона)
Ниже приведен простой пример для шаблонных mixins, где мы создаем шаблон с классом Department и mixin, создающий экземпляр шаблона, и, следовательно, делаем функции setName и printNames доступными для структуры college.
import std.stdio; template Department(T, size_t count) { T[count] names; void setName(size_t index, T name) { names[index] = name; } void printNames() { writeln("Названия"); foreach (i, name; names) { writeln(i," : ", name); } } } struct College { mixin Department!(string, 2); } void main() { auto college = College(); college.setName(0, "название1"); college.setName(1, "название2"); college.printNames(); }
Когда вы скомпилируете и выполните эту программу, она возвратит следующий результат:
Названия 0 : название1 1 : название2
Mixins пространств имён используются, чтобы избежать неоднозначностей в шаблонных mixins. Например, могут существовать две переменные, одна из которых явно определена в коде основной программы, а другая – в примешанном. Когда примешанное имя совпадает с именем, находящимся в окружающей области видимости, тогда основным является имя, находящееся в окружающей области. Доступ к примешанному имени осуществляется через имя mixin'а. Этот пример показан ниже.
import std.stdio; template Person() { string name; void print() { writeln(name); } } void main() { string name; mixin Person a; name = "имя 1"; writeln(name); a.name = "имя 2"; print(); }
Когда вы скомпилируете и выполните эту программу, она возвратит следующий результат:
имя 1 имя 2