2016-06-08 31 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可以釋放它,但你不能)。 –