2016-06-08 55 views
2
immutable auto a = Array!int([1, 2, 3]); 

Error: cannot implicitly convert expression (((Array!int __slArray2557 = Array(RefCounted(RefCountedStore(null)));) , __slArray2557).this([1, 2, 3])) of type Array!int to immutable(Array!int)创建用户定义的不可变对象

通常我只是想在运行时创建一些对象,初始化它,然后让它不变,但如果我尝试这样做,我从上面得到的错误。

看来,我可以投一个可变对象不可变对象

immutable auto a = cast(immutable Array!int) Array!int([1, 2, 3]); 

为什么我必须将它转换为immutable

正在铸就永恒的合法吗?

+0

我几乎对D几乎一无所知,但是如果你将变量声明为不可变的,编译器可能会期望右边的表达式是不可变的对象,所以当然如果不是这种情况,它可能会给你一个错误。关于合法与否,我不知道,但如果您没有收到答复,我建议您在官方网站的D论坛之一上提出同样的问题。 – nbro

回答

6

由于Array被引用计数,它现在是不是一成不变的兼容 - 它保持一个指向它里面的引用计数,如果它是不可变的,不能改变,打破了整个事情。演员只是绕过规则,编制但未定义的行为。

如果是不变的,只是沟Array包装,并使用一个普通的切片:

// this works fine 
immutable a = [1, 2, 3]; 

(赫克,数组封装基本上是无用的,如果你反正传递文字,因为普通的数组构造只是传递给它的构造,它得到再次构建!)

BTW在immutable autoauto是不必要的,你可以把它叫做immutable

你也可以创建一个不可变数据的可变数组,这也应该工作 - 因为它的内存管理方案,它只是需要可变性。

+0

有什么可以不可变的文件吗?看来,当我创建包含指针或切片的自定义类型时,它不可能是不可变的。我想我真正想要的可能只是const。 –

+0

const不能用于引用计数。但是一般来说,如果你想知道一个类型是用const还是不可变的,可以先查看它的成员函数,看看哪些是const,不可变或inout。没有任何函数的函数肯定不会用'const'或'immutable'。如果足够的这些属性被标记为那些属性,那么它可能会起作用,但如果文档没有说明,并且你没有处理一个相当简单的类型,那么很可能“不可变”将不起作用。另一个好的线索是如果它可以被构建为不可变的。 –

+0

我认为这是关于immutable的最新文章:http://dlang.org/spec/const3.html,但基本上规则是只要你输入const/immutable land,你就永远不会离开它。所以如果外层是不可变的,那么所有的成员以及成员指向的所有数据等等。一个不可变的变量不能被任何东西修改 - 包括内部指针调整大小和释放,还包括结构赋值。只有当它没有更多的引用时,它才能被释放,所以程序永远不会知道它只是一种错觉(因此GC可以释放它,但你不能)。 –