【问题标题】:Changing immutable members inside the constructor在构造函数中更改不可变成员
【发布时间】:2012-08-08 08:28:34
【问题描述】:
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) 不行?两者的行为不应该相同吗?

【问题讨论】:

  • 但这会让事情变得太容易了。 :P
  • 这很有趣:void increment(int i, out int j) { j = i + 1; },你用increment(member, member) 调用它。

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


【解决方案1】:

可能是因为对increment的引用不是scope,所以它有可能逃过构造函数的作用域,这会破坏member的不变性,编译器无法验证没关系。

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

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

【讨论】:

    【解决方案2】:

    如果increment 是这个呢?

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

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

    【讨论】:

      【解决方案3】:

      我猜

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

      等价于

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

      在 C++ 中。

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

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

      【讨论】:

      • Ideone 有一个旧版本 - 2.042。所以我想我会接受彼得亚历山大的回答。
      猜你喜欢
      • 2019-07-20
      • 2015-05-12
      • 2018-09-06
      • 2016-12-22
      • 2011-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-07
      相关资源
      最近更新 更多