根据我在阅读D时的理解,在变量上使用immutable关键字时,必须在编译时知道变量的值,而C#的readonly不必是已知的,并且readonly字段可以在类构造函数中使用non -静态值。 D有可能吗?

最佳答案

由于似乎对不可变存在一些混淆(从原始问题和he_the_great的评论来看),我想我会放在一旁。

当您说immutable int i = 42时,您是在说我不会被修改,不是说它的值在编译时是已知的。 immutable实际上是一个类型修饰符,并创建一个新的类型。 immutable Timmutable(T)的简写。 immutable(T)创建一个永远不会突变的T,也就是说,如果您读取该值,然后调用一个函数,则该值将是相同的。将此与const(T)进行比较,它可以提供较弱的保证,即不会修改此类型的实例,但是其他地方可能有人对它具有可变的访问权,因此,如果您读取该值然后调用一个函数,则不能假设该值将是相同。

通常,immutable(T) != T。但是,在某些情况下它们可以隐式转换为彼此。例如,如果T是被认为没有“可变间接”的类型。就是说,如果我将一个immutable(int)传递给函数,则它们会收到一个副本-该函数无法在复制时修改我传递的值-如果类型系统不允许,它将被复制。没有附加的保证就很烦人了,所以D类型的系统允许它。但是,如果我传递了不可变(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的情况下调用方法。

对于题外杂乱,我深表歉意,但我发现很多人对此主题感到困惑。

关于c# - 等价于D中的C# `readonly`关键字?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6036807/

10-10 18:43