簡體   English   中英

D中C#`readonly`關鍵字的等價物?

[英]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 Timmutable(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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM