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

Nic*_*Lee 7 final mixins dart flutter

我正在使用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?
}
Run Code Online (Sandbox Code Playgroud)

Salt没有构造函数,所以我不能使用初始化列表。pinchesfinal,因此无法在Meat的构造函数中进行设置。

我不想Salt上课,因为Meat可能需要扩展其他内容。

我想保持pinches不变。

有办法吗?提前致谢。

Rém*_*let 25

您可以将 mixin 的声明更改为:

mixin Salt {
  int get pitches;
}
Run Code Online (Sandbox Code Playgroud)

然后在实现类里面定义字段

class Meat with Salt {
  final int pitches;
  Meat(this.pitches);
} 
Run Code Online (Sandbox Code Playgroud)

  • Mixin 不是用来声明变量的。但是对于可重用的方法 (11认同)
  • 在这种情况下使用 `mixin` 有什么意义,如果我们应该以这种方式复制代码? (3认同)

Nat*_*son 7

我对此提出我的解决方案。通过标记变量,late您可以创建它final。如果初始化失败,不会出现任何警告,因此请谨慎使用。

mixin Salt {
  late final int pinches;
}

class Vegetable with Salt {
  Vegetable(int pinches) {
    this.pinches = pinches;
  }
}
Run Code Online (Sandbox Code Playgroud)


att*_*ona 5

根据设计,不可能将 final 成员声明为 mixin,因为不可能声明用于初始化最终成员的构造函数,引用文档

然而,在这个提议中,mixin 只能从没有声明构造函数的类中提取。此限制避免了由于需要将构造函数参数向上传递到继承链而出现的复杂情况。

一种妥协可能是声明一个私有成员并仅实现一个 getter。
_pinches仅在图书馆内可见,对图书馆用户是只读的。

mixin Salt {
  int _pinches;

  get pinches => _pinches;

}

class Meat with Salt {

  Meat(int pinches)  {
   _pinches = pinches;
  }
}
Run Code Online (Sandbox Code Playgroud)

注意:由于可见性规则,上述模式仅在 mixin 和混合类驻留在同一个库中时才有效。

  • 我可以接受两个答案,因为@attdona 和@RémiRousselet 一起给出了全貌吗?@RémiRousselet 的建议可行,但它违背了在 mixin 中保存数据的目的。在@attdona 的建议中,`_pinches` 并不是严格不变的。你们一起确认没有理想的解决方案。我对这两个答案都投了赞成票,但很抱歉没有(完全)接受。 (4认同)