Menu

Атрибуты

В D функциям можно назначить атрибуты различными способами. Давайте рассмотрим пару встроенных атрибутов, а также атрибуты, определяемые пользователем. Напомним, что также существуют встроенные атрибуты @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;
}

Атрибуты, определяемые пользователем (UDA)

Любой функции и любому типу в D можно назначить атрибуты, определяемые пользователем:

struct Bar { this(int x) {} }

struct Foo {
  @("Hello") {
      @Bar(10) void foo() {
        ...
      }
  }
}

Любой тип, как встроенный, так и определяемый пользователем, можно использовать как атрибут функции. В данном примере функции foo() назначается два атрибута: "Hello" (тип string) и Bar (тип Bar со значением 10). Чтобы получить список атрибутов функции, используйте встроенный типаж __traits(getAttributes, Foo), который возвращает TypeTuple.

UDA позволяют обогатить обобщённый код, открывая новую метрику для типов, что помогает генераторам кода, работающим во время компиляции, подстроиться под конкретный тип.

Подробнее

rdmd playground.d