【问题标题】:meaning of const in `const ['foo', 'bar']` in dartdart 中 `const ['foo', 'bar']` 中 const 的含义
【发布时间】:2015-01-13 11:28:24
【问题描述】:

我知道 const 是 dart 中的编译时常量,但我不明白以下代码中 const [F0, F1, F2] 背后的机制:

class Foo {
  static const F0 = 'F0';
  static const F1 = 'F1';
  static const F2 = 'F2';
  // const list of const values I guess...
  static const CONST_LIST = const [F0, F1, F2]; // please explain this line
  static final String FOO = CONST_LIST[0]; // ok
  // compile error: 'const' varaibles must be constant value
  // static const String BAR = CONST_LIST[1];
}

main() {
  // is CONST_LIST const or not?
  // below line it's ok for dartanalyzer but
  // in runtime: Cannot change the content of an unmodifiable List
  Foo.CONST_LIST[1] = 'new value';
}

我注意到const [F0, F1, F2]; 中的 dart 分析器需要 const,但它确实使列表更像 final(运行时不可变列表)而不是编译时常量。

更新:

另一个问题是为什么CONST_LIST[1] 不是“恒定值”。请参阅Foo.BAR 的注释声明。

【问题讨论】:

  • Const 对象必须具有深度不变性。所以如果你有 const 变量,它应该引用由 const 对象组成的 const 对象。
  • 是什么让你觉得这让它更像是一场决赛? static const String BAR = CONST_LIST[1] 的问题是常量表达式当前不支持数组访问器(请参阅dartbug.com/18389)。似乎是 Dart 分析器中的一个错误。
  • @JAre:CONST_LIST 中什么是可变的?它被声明为 const,所有值都是 const 的 const 列表。怎么可能更 const? ;-)
  • @GünterZöchbauer 分析器在分配“新值”时无法检测到问题。您指出的错误使其更加清晰。谢谢。

标签: dart constants


【解决方案1】:

对此有一个未解决的错误:请参阅https://github.com/dart-lang/sdk/issues/3059

【讨论】:

    【解决方案2】:

    Günter 已回答您问题的第二部分。以下是有关 const 的更多信息。

    Const 意味着对象的整个深度状态可以完全在编译时确定,并且对象将被冻结并且完全不可变。

    更多信息请参见article。另请参阅以下question

    关于问题的第二部分,请考虑以下几点:

    const int foo = 10 * 10;
    

    表达式“10 * 10”可以在编译时求值,所以它是一个“常量表达式”。您可以在常量表达式中执行的操作类型需要非常有限(否则您可以在编译器中运行任意 Dart 代码!)。但是随着 dart 的成熟,其中一些限制正在放宽,正如您在 Günter 所链接的错误中看到的那样。

    相比之下,请考虑以下几点:

    final int bar = 10;
    final int foo = bar * bar;
    

    由于“bar * bar”不是一个常量表达式,它在运行时被计算。

    【讨论】:

    • 所以由于[] 操作符的复杂性,dart 编译器还不够聪明,无法计算出CONST_LIST[1] 的值?
    • 是的——可能是因为在 Dart 中你可以覆盖 [] 运算符,所以这与调用方法基本相同。
    • 迂腐:10 * 10 表达式一个编译时常量表达式,将在编译时计算。如果你然后写final int bar = foo * foo;,那么那个表达式不是常量,因为foo是一个非常量变量。如果foo 是常量,那么foo * foo 也将是常量。
    • 非常感谢。我已经更新了评论。我希望我现在通过迂腐测试;)
    猜你喜欢
    • 1970-01-01
    • 2022-01-12
    • 2021-04-21
    • 2015-07-16
    • 2016-02-11
    • 2012-04-19
    • 2011-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多