属性

Dでは関数は様々な方法で属性付けできます。 2つの組み込み属性とユーザ定義属性を見てみましょう。 最初のチャプターで言及された組み込みの @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;
}

ユーザ定義属性 (UDAs)

Dの任意の関数や型はユーザ定義型で属性付けできます:

struct Bar { this(int x) {} }

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

組み込みまたはユーザ定義の任意の型は、関数に属性付けできます。 このサンプルの関数foo()"Hello" (string型)と Bar (値10でのBar型)で属性付けされます。関数(もしくは型) の属性を取得する際は組み込みのコンパイラトレイト __traits(getAttributes, Foo)を使い、これは TypeTupleを返します。

UDAはコンパイル時ジェネレータが特定の型に適応するのを助ける 別の次元のユーザ定義型によりジェネリックコードを強化することができます。

掘り下げる

rdmd playground.d