在构造函数中更改不可变成员

时间:2012-08-08 08:28:34

标签: constructor initialization pass-by-reference d immutability

void increment(ref int i)
{
    ++i;
}

class Class
{
    immutable int member;

    this(int parameter)
    {
        member = parameter;
        ++member;           // okay
        increment(member);  // compile-time error
    }
}

为什么++member没问题,但increment(member)不是?这两种行为不应该相同吗?

3 个答案:

答案 0 :(得分:5)

可能是因为对increment的引用不是scope,所以它有可能被转义超出构造函数的范围,这会破坏member的不变性,并且编译器无法验证它没问题。

scope也可能不起作用,但应该。如果实施得当,我认为scope会修复批次像这样的错误,以及提供有趣的优化。如果没有,我会说这是一个错误。)

我之前已经指出了半类似的错误,但是与代表们有关 Const / immutable在D中确实存在这样的问题。

答案 1 :(得分:3)

如果这是increment怎么办?

int* p;
void increment(ref int i)
{
    p = &i;
}

哦,你已经创建了一个对不可变数据的可变引用,破坏了类型系统。

答案 2 :(得分:0)

我在猜测

this(int parameter) {
    member = parameter;
    ++member;
}

相当于

Class(int parameter): member(parameter+1) {}

在C ++中。

我认为member字段在构造函数中并不是真正可变的,因此编译器可以优化它以只是初始化它。但它不能通过调用另一个函数来做到这一点。

PS。它适用于ideone:http://ideone.com/5ym5u