[英]Equivalent of C# `readonly` keyword in D?
根據我在閱讀D時的理解,當在變量上使用immutable
關鍵字時,變量的值必須在編譯時知道,而C#的readonly
不需要,並且readonly
字段可以在類構造函數中使用non分配 - 靜態價值觀。 這可能在D?
在D2中,const成員只能在構造函數內初始化(或直接在類聲明中初始化,但不能同時在兩者中):
import io = std.stdio;
class A
{
const int member;
this(int nb)
{
this.member = nb;
}
}
void main()
{
A a = new A(12);
io.writeln(a.member);
//a.member = 14; //Error: can only initialize const member member inside constructor
}
由於關於不可變的問題似乎存在一些混淆(來自原始問題和he_the_great的評論),我想我會補充一點。
當你說immutable int i = 42
,你說我不會被修改,而不是在編譯時知道它的值。 immutable
實際上是一個類型修飾符,並創建一個新類型。 immutable T
是immutable(T)
的簡寫。 immutable(T)
創建一個永遠不會變異的T,也就是說,如果你讀取了值,然后調用一個函數,那么值就是相同的。 將此與const(T)
進行比較,它提供了較弱的保證,即該類型的實例不會被修改,但有人可能對其他地方進行了可變訪問,因此,如果您讀取該值然后調用函數,則不能假設價值會是一樣的。
通常, immutable(T) != T
然而,在某些情況下,它們可以隱含地相互轉換。 例如,如果T是一種被認為沒有“可變間接”的類型。 也就是說,如果我傳遞一個函數一個immutable(int)
,它們會收到一個副本 - 如果類型系統不允許,那么該函數無法修改我傳遞的值,因為它被復制了如果沒有額外的保證就會很煩人,所以D型系統允許它。 但是,如果我傳遞一個immutable(int *),那么可以通過調用函數進行更改。 在結構的情況下,如果任何成員具有可變間接,那么結構也被稱為具有它。
因此,為了擺脫理論並回到更實際的問題,根本不可能在編譯時知道不可變值,並且沒有好的方法來創建它們。 但是,唯一的突變可能發生在構造函數內部。 對於簡單的標量類型,這很明顯:
immutable(int) i = rand();
但是像對象一樣呢? 好吧,構建我們使用的類型T.
auto t = new T();
所以要構造我們使用的類型immutable(T)
auto t = new immutable(T)();
這是一個更完整的小例子
class Useless
{
int i;
this(int i)
{
this.i = i;
}
}
int main(string[] args)
{
auto o = new immutable(Useless)(cast(int) args.length);
//o.i = 17; error
return o.i; // fine
}
如您所見,構造函數內部可能發生變異。 您可以讀取成員變量,但不能寫它們(不可變是傳遞性的;也就是說,如果父進程,每個成員(以及成員的每個成員)都變為不可變。只有當它們被標記為const
才能調用方法。
我為偏離話題的漫無邊際道歉,但我看到很多人似乎對這個話題感到困惑。
fwend的答案基本上是死的,但如果你正在尋找一些不那么冗長的東西,你可以隨時制作一個mixin來自動化它。 下面未經測試的代碼給出了一般的想法:
string readOnly(string typeName, string varName) {
// Create a private variable that prepends an _ to the name and a
// public accessor named name.
return "private " ~ typeName ~ " _" ~ varName ~ ";\n" ~
"public " ~ typeName ~
"varName() @property { return _" ~ varName ~ ";\n";
}
用法:
class Foo {
mixin(readOnly("int", "num"));
void incNum() {
_num++;
}
}
我將該字段聲明為私有,然后使用get訪問器來讀取它
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.