1

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

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

但是 DartEditor 在 fromJson 方法的 case 语句中抱怨“预期的常量表达式”。有没有我可以在某处扔掉这个投诉的 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;
    }
  }
}
4

1 回答 1

3

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

With the current syntax there is no way to express a (informal) contract that a field of a class will always be a final field. For example, I could change the value-field to be a getter instead of a field. The interface-contract of the class definitely allows me to do that, because I never told anybody that I would keep "value" as a field. However if I did that it would break every program that relied on the existence of this final field.

As a consequence the current behavior is very unlikely to change.

However: in theory it would be possible to improve the Dart language so that you could use "const" instead of "final" for local fields, and initialize them with initializer lists. And in this case accessing the field could be considered a constant operation. I currently don't see any downsides to this behavior and it would be backwards-compatible.

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

The language is already pretty stable but you can open a bug at http://dartbug.com/ and suggest this behavior. It's not very likely that the feature-request would be accepted, but it's definitely worth a try.

于 2013-03-30T14:36:17.393 回答