Dart构造函数可选参数默认值报错:为何Staff实例不能作为默认值?
Dart构造函数可选参数默认值报错问题解析
问题背景
首先定义了Staff类:
class Staff { final String name; final String id; Staff({this.name, this.id}); }
随后将Staff实例放入SignInState类的构造函数参数中,代码如下:
class SignInState { final String href; final Staff staff; SignInState({this.href = '', this.staff= Staff(name:'', id:'')}); }
此时在this.staff= Staff(name: '', id: '')处收到错误提示:
The default value of an optional parameter must be constant.
但如果改成类内直接初始化的写法final Staff staff = Staff(name: '', id: '')却可以正常运行,这是为什么?
原因解析
- 构造函数可选参数的硬性规则:Dart明确要求,构造函数的可选参数默认值必须是编译时常量。
Staff(name:'', id:'')是程序运行时才会创建的实例,不属于编译时常量,所以没法作为可选参数的默认值。 - 类内成员初始化的逻辑差异:类内直接写
final Staff staff = Staff(name: '', id: '')属于对象实例化阶段的运行时初始化逻辑,不受“必须为常量”的限制,因此能正常执行。
解决办法
针对这个问题,有两种常见的可行方案:
方法一:把Staff构造改成const构造
如果Staff的所有成员都是不可变类型(比如这里的String),可以将Staff的构造函数声明为const构造,这样它创建的实例就属于编译时常量:
class Staff { final String name; final String id; const Staff({this.name = '', this.id = ''}); }
之后就能用const修饰的Staff实例作为默认值:
class SignInState { final String href; final Staff staff; SignInState({this.href = '', this.staff = const Staff(name:'', id:'')}); }
方法二:通过构造初始化列表处理默认值
如果不想修改Staff类,可以在SignInState的构造函数初始化列表中,用空联合运算符处理staff的默认值:
class SignInState { final String href; final Staff staff; SignInState({String href = '', Staff? staff}) : href = href, staff = staff ?? Staff(name:'', id:''); }
内容的提问来源于stack exchange,提问作者Konayuki
相关产品推荐
相关产品推荐

