我如何进行一成不变的类(class)?

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

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

别名真的是执行此操作的最佳方法吗?
不变关键字对类定义有什么作用?
如果不执行任何操作,这不应该是某种警告或错误吗?

(在Windows 8上将Xamarin Studio与dub和DMD32 D编译器v2.066.0一起使用)

最佳答案

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

http://dlang.org/class.html
如果ClassDeclaration具有const,不可变或共享的存储类,则好像该类的每个成员都是使用该存储类声明的。如果基类是const,不可变或共享的,则从该基类派生的所有类也是const,不可变或共享的。

因此,它可以避免您对内部所有内容设置不可变的内容,并且也适用于继承。但是它并不会改变类型本身-Data仍然是对所有不可变数据的可变引用(顺便说一句有时可能很有用,因为它可以很容易地重新绑定(bind)到另一个实例)。您的别名实现了整个类型更改。

顺便说一句,还要为您的不可变类添加一个构造函数。即使它只是空的,一个不可变的构造函数的存在(如果将不可变的放在外面就可以了)将完全禁止可变构造:

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)

根据您的喜好。

10-06 14:52