我正在使用Dart 2.1.0在Flutter中进行编程,遇到这种情况:
mixin Salt {
final int pinches; // Immutable, and I want to delay initialization.
// Cannot declare constructors for mixin
}
class Meat with Salt {
Meat(int pinches) ... // How to initialize it?
}
Salt
没有构造函数,因此无法使用初始化列表。 pinches
是final
,因此我无法在Meat
的构造函数中进行设置。
我不想将Salt
当作一门课,因为Meat
可能需要从其他内容中扩展出来。
我想保持pinches
不变。
有什么办法吗?预先感谢。
答案 0 :(得分:2)
您可以将mixin的声明更改为:
mixin Salt {
int get pitches;
}
然后在实现类中定义字段
class Meat with Salt {
final int pitches;
Meat(this.pitches);
}
答案 1 :(得分:2)
通过设计,无法将最终成员声明为mixin,因为无法声明用于初始化最终成员的构造函数, 引用the docs:
但是,在此建议中,只能从没有声明的构造函数的类中提取mixin。此限制避免了由于需要将构造函数参数传递到继承链而引起的复杂性。
一个折衷方案可能是声明一个私有成员并仅实现一个getter。
_pinches
仅在库内部可见,对库用户是只读的。
mixin Salt {
int _pinches;
get pinches => _pinches;
}
class Meat with Salt {
Meat(int pinches) {
_pinches = pinches;
}
}
注意:由于可见性规则,上述模式仅在mixin和混合类位于同一库中时有效。
答案 2 :(得分:1)
以下方法可让您稍后设置数据,并摆脱警告:
This class (or a class that this class inherits from) is marked as '@immutable', but one or more of its instance fields aren't final
mixin Salt {
final SaltData _saltData = SaltData();
int get pinches => _saltData.pinches;
set pinches(int extraData) {
_saltData.pinches = extraData;
}
}
class SaltData {
int pinches = 0;
}
所以我要做的是创建一个类SaltData
。这将存储您需要的所有变量。
私有_saltData
变量是最终变量,这将停止警告。
然后使用getter和setter来检索和更新数据。
int get pinches => _saltData.pinches;
set pinches(int extraData) {
_saltData.pinches = extraData;
}
如果需要,您也可以公开整个saltData对象:
SaltData get saltData => _saltData;
答案 3 :(得分:0)
类似于atddona的建议,但是更接近您真正想要的,您可以这样做
mixin Salt {
int _pinches;
int get pinches => _pinches;
void initSalt(int pinches) {
assert(_pinches == null);
_pinches = pinches;
}
}
class Meat with Salt {
Meat(int pinches) {
initSalt(pinches);
}
}
它仍然不是严格的最终版本,但是(只要mixin位于另一个库中,因此您不能直接更改私有成员),它在运行时是不可变的。好像不能完全定型,但可能足够接近。