У мові D функції можуть використовуватись як атрибути різними
способами. Давайте подивимось на два вбудовані атрибути, на user-defined
attributes (задані користувачем атрибути), а також на вбудовані атрибути
@safe, @system і @trusted, що згадувалися у першому розділі.
@propertyФункція позначена як @property виглядає нормальним членом для
зовнішнього світу
struct Foo {
@property bar() { return 10; }
@property bar(int x) { writeln(x); }
}
Foo foo;
writeln(foo.bar); // насправді викликає foo.bar()
foo.bar = 10; // викликає foo.bar(10);
@nogcКоли компілятор мови D зустрічає функцію, позначену як @nogc,
він переконається, що буде відсутнє виділення пам'яті у межах
контексту цієї функції. Функція @nogc має властивість викликати
також інші функції @nogc.
void foo() @nogc {
// ПОМИЛКА:
auto a = new A;
}
Будь-яка функція чи тип у мові D може бути використана як атрибут з заданим користувачем типом.
struct Bar { this(int x) {} }
struct Foo {
@("Hello") {
@Bar(10) void foo() {
...
}
}
}
Будь-який тип, вбудований або визначений користувачем, може використовуватись
як атрибут функцій. Функція foo() у цьому прикладі матиме атрибути
"Hello" (тип string) і Bar (тип Bar із значенням 10).
Щоб отримати атрибути функції (або типу), використовуйте метод вбудованого
компілятора traits __traits (GetAttributes, Foo), який повертає
AliasSeq.
UDAs дозволяє посилити загальний (generic) код, надаваючи створеним користувачем типам інший вимір, що допомогає компілятору адаптуватися до цього конкретного типу під час компіляціі.