Dart const表达式调用重载+运算符报操作数需为num类型原因
核心原因
Dart对常量表达式允许执行的操作有严格的白名单限制,和操作数本身是不是常量没有直接关系:
- 自定义重载的
+运算符本质是普通实例方法,Dart的编译期常量求值器不会执行任意用户编写的实例方法。常量求值需要在编译阶段就得出确定结果,如果允许执行任意用户自定义方法,编译器需要内嵌完整Dart运行时,还要规避方法逻辑可能带来的副作用,实现复杂度和风险都极高。 - 报错
In constant expressions, operands of this operator must be of type 'num'的本质是:常量表达式中仅允许对内置num类型(int/double)使用加减乘除这类算术运算符,在常量上下文里对自定义类实例调用+操作,不在常量操作的允许范围内,直接触发编译校验失败。 - 认知偏差纠正:
const修饰的值并非运行时创建,而是在编译期就完成求值、规范化生成的标准实例,整个编译求值过程不会执行你写在类中的自定义运算符逻辑。
不同声明方式的差异
- 用
const声明objectC时,要求赋值号右侧整体是合法常量表达式,必须在编译期计算出确定值,调用自定义+运算符的写法不符合常量表达式规则,因此编译失败。 - 用
final声明objectC时,不要求编译期完成求值,+运算符的逻辑会在运行时正常执行,因此可以正常运行。
如果要得到const修饰的MyClass实例,不能依赖重载的运算符,必须直接调用const构造函数,且传入的所有参数都属于合法常量,例如以下写法是合法的:
const objectC = MyClass(1 + 3, 4 + 2);
这里的1 + 3、4 + 2是num类型的内置加法运算,属于常量表达式允许的操作,最终会在编译期直接生成const的MyClass实例。
内容的提问来源于stack exchange,提问作者Suragch
相关产品推荐
相关产品推荐

