D中不可变的类

时间:2014-12-06 23:09:45

标签: d

如何创建不可变类?

我的目标是创建一个实例总是不可变的类。现在我只使用不可变方法和构造函数创建一个“可变”类。我称它为mData,m为可变。然后我创建一个别名alias immutable(mData) Data;并在任何地方使用它而不是类名。这很好用,但似乎没必要。

如果我使用immutable(immutable class Data{...})标记类定义,那么不会使用类。因此,如果我从另一个类或函数中使用它并调用一个不可变的方法(它们都是),编译器就会抱怨在一个可变对象上调用一个不可变的方法,即使按定义这个类是不可变的!为了解决这个问题,我必须在类型名称前面添加不可变关键字。这是别名真正为我做的。

别名真的是最好的方法吗? 不可变关键字对类定义有什么作用? 如果它什么也不做,那不应该是某种警告或错误吗?

(在Windows 8上使用带有dub和DMD32 D编译器v2.066.0的Xamarin Studio)

1 个答案:

答案 0 :(得分:5)

我认为别名最好的方法,加上课外的不可变。后者的作用是:

http://dlang.org/class.html 如果ClassDeclaration具有const,immutable或shared存储类,那么就好像该类的每个成员都使用该存储类声明一样。如果基类是const,immutable或shared,那么从它派生的所有类也是const,immutable或shared。

因此它可以避免在内部的所有内容上设置不可变,也适用于继承。但它并没有改变类型本身 - Data仍然是一个可变引用,只是对所有不可变数据(btw有时可能很有用,因为它可以很容易地重新绑定到另一个实例)。你的别名实现了类型的整体变化。

BTW,也为你的不可变类添加一个构造函数。即使它只是空的,一个不可变的构造函数的存在(如果你把不可变的东西放在外面就是全部)将完全禁止可变构造:

immutable class Foo { }

Foo foo = new Foo(); // permitted. All the data will be immutable, but it will let you construct it this way

immutable class Foo {
    this() {} 
}         

Foo foo = new Foo(); // Error: immutable method test100.Foo.this is not callable using a mutable object

那么你想用

构建它
auto foo = new immutable Foo(); // (infers based on right hand side)

你也可以把它写成:

immutable foo = new immutable Foo(); // (infers always to an immutable type)

immutable(Foo) foo = new immutable Foo(); // (explicitly writing the immutable type)

取决于您的喜好。