Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
D 是否存在与Ruby';s属性存取器_D - Fatal编程技术网

D 是否存在与Ruby';s属性存取器

D 是否存在与Ruby';s属性存取器,d,D,在Ruby中,我可以轻松地设置类的读/写属性,如下所示: class Bar attr_accessor :foo, :bizz, :buzz end 这将与 class Bar def foo @foo end def foo=(foo) @foo = foo end def bizz @foo end def bizz=(bizz) @bizz = bizz end def buzz @buzz e

在Ruby中,我可以轻松地设置类的读/写属性,如下所示:

class Bar
  attr_accessor :foo, :bizz, :buzz
end
这将与

class Bar
  def foo
    @foo
  end

  def foo=(foo)
    @foo = foo
  end

  def bizz
    @foo
  end

  def bizz=(bizz)
    @bizz = bizz
  end

  def buzz
    @buzz
  end

  def buzz=(buzz)
    @buzz = buzz
  end
end
同样的代码是D,非常冗长,我发现自己到处都在重复:

class Bar {
  private {
    string _foo, _bizz, _buzz;
  }

  @property {
    string foo()  { return _foo;  }
    string bizz() { return _bizz; }
    string buzz() { return _buzz; }

    void foo(string foo)   { _foo = foo;   }
    void bizz(string bizz) { _bizz = bizz; }
    void buzz(string buzz) { _buzz = buzz; }
  }
}
有没有简捷的方法可以做到这一点?

是:

public string foo;
在我看来,琐碎的属性访问器是浪费时间的。Ruby强迫您这样做,但D不这么做

如果仍然需要它们,则mixin模板可以执行以下操作:

mixin template attr_accessor(Type, string name) {
    static string codeGenerationHelper() {
        string code;
        // the variable
        code ~= "private Type _" ~ name ~ ";";

        // the getter
        code ~= "public @property Type " ~ name ~ "() { return _" ~ name ~ "; }";

        // the setter
        code ~= "public @property Type " ~ name ~ "(Type a) { return _" ~ name ~ " = a; }";

        return code;
    }

    mixin(codeGenerationHelper());
}

// here's how to use it
class Foo {
    mixin attr_accessor!(string, "foo");
}

void main() {
    auto foo = new Foo();
    foo.foo = "test";
}

你能给我解释一下
codeGenerationHelper()
位吗?是的,你要做的就是把D代码构建成一个大字符串。然后,下面的mixin表达式告诉编译器将代码粘贴到这里并编译所有代码。所以在这里,我们考虑了代码的样子:一个变量定义,一个getter,然后是setter函数。所以我们在这个helper函数中所做的就是构建那个字符串。D中的
~
运算符是string append/concat。我们经常分解字符串以插入变量的名称。否则,语法看起来可能比引号更难,但它只是粘贴在一起的纯D代码。是的,您可以分别执行attr_reader和attr_writer,但需要注意不要两次声明变量。在我的示例中,我在生成的代码字符串中声明了私有变量。这应该只做一次,所以其他两个属性需要处理这个问题。实际上,可能会有,但通常你会使用
static if(is(Type==some_-Type_-name)){/*在这里做点什么*/}
,然后
else static if(其他东西)
等等。是的,它可以使用反射来检查类中是否存在变量,但这太复杂了,无法在注释中解释。。。