应该从const对象返回const值是const?

时间:2013-03-30 13:42:44

标签: dart

我正在使用下面的样式类来模仿枚举(来自Does Dart support enumerations?) 它的工作正常,因为这个片段产生了预期的结果。

void main() {
  InterpolationType it = InterpolationType.LINEAR;
  print("it is $it and stringified ${stringify(it)}");
  print(InterpolationType.fromJson(it.toJson()));
}

但DartEditor在fromJson方法的case语句中抱怨“Expected constant expression”。我是否可以在某个地方投掷一个const来摆脱这种抱怨?

class InterpolationType { 
  static const LINEAR = const InterpolationType._(0);
  static const STEP = const InterpolationType._(1);
  static const CUBIC = const InterpolationType._(2);

  static get values => [
    LINEAR,
    STEP,
    CUBIC
  ];

  final int value;

  const InterpolationType._(this.value);

  String toString() { 
    switch(this) { 
      case LINEAR: return "LINEAR";
      case STEP: return "STEP";
      case CUBIC: return "CUBIC";
    }
  }

  int toJson() { 
    return this.value;
  }

  static InterpolationType fromJson(int v) { 
    switch(v) { 
      case LINEAR.value: return LINEAR;
      case STEP.value: return STEP;
      case CUBIC.value: return CUBIC;
    }
  }

  static InterpolationType fromString(String s) { 
    switch(s) { 
      case "LINEAR": return LINEAR;
      case "STEP": return STEP;
      case "CUBIC": return CUBIC;
    }
  }
}

1 个答案:

答案 0 :(得分:2)

正如您所发现的:从const对象访问字段不是一个常量操作。所以编辑器(以及VM和dart2js)都是对的。

使用当前语法,无法表达(非正式)合同,类的字段始终是最终字段。例如,我可以将value-field更改为getter而不是field。这个班级的接口合同绝对允许我这样做,因为我从来没有告诉过任何人我会把“价值”作为一个领域。但是,如果我这样做,它将打破依赖于最终字段存在的每个程序。

因此,目前的行为不太可能改变。

但是:理论上可以改进Dart语言,以便您可以对本地字段使用“const”而不是“final”,并使用初始化列表初始化它们。在这种情况下,访问该字段可被视为常量操作。我目前没有看到这种行为的任何缺点,它将向后兼容。

// WARNING: What follows DOES NOT WORK, just a potential example
class InterpolationType {
  const value;  // Note the "const" instead of "final".
  const InterpolationType._(this.value);
}

该语言已经相当稳定,但您可以在http://dartbug.com/打开一个错误并提出此行为。这个功能请求不太可能被接受,但绝对值得一试。