如何在Dart中初始化mixin的不可变数据?

时间:2019-01-13 07:26:51

标签: dart flutter mixins final

我正在使用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没有构造函数,因此无法使用初始化列表。 pinchesfinal,因此我无法在Meat的构造函数中进行设置。

我不想将Salt当作一门课,因为Meat可能需要从其他内容中扩展出来。

我想保持pinches不变。

有什么办法吗?预先感谢。

4 个答案:

答案 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位于另一个库中,因此您不能直接更改私有成员),它在运行时是不可变的。好像不能完全定型,但可能足够接近。