我有Android开发背景,正在学习Flutter。
在Android中,通常的做法是使用Kotlin密封类从ViewModel返回状态,例如
sealed class MyState {
data class Success(val data: List<MyObject>) : MyState()
data class Error(val error: String) : MyState()
}
Run Code Online (Sandbox Code Playgroud)
我想在Flutter中使用类似的模式,并从BLOC类返回一个State对象。在Flutter中实现相同效果的最佳方法是什么?
很快 Dart 将支持密封类。
GitHub 代码:来源
sealed class Either {}
class Left extends Either {}
class Right extends Either {}
Run Code Online (Sandbox Code Playgroud)
您现在可以测试密封类
test(Either either) {
switch (either) {
case Left(): print('Left');
case Right(): print('Right');
}
}
Run Code Online (Sandbox Code Playgroud)
这样的用例将使用命名工厂构造函数来完成。
它需要很多代码,但是行为是相同的。
class MyState {
MyState._();
factory MyState.success(String foo) = MySuccessState;
factory MyState.error(String foo) = MyErrorState;
}
class MyErrorState extends MyState {
MyErrorState(this.msg): super._();
final String msg;
}
class MySuccessState extends MyState {
MySuccessState(this.value): super._();
final String value;
}
Run Code Online (Sandbox Code Playgroud)
R\xc3\xa9mi Rousselet的答案在某种程度上是正确的,但作为sindrenm提到的:
\n\n\n\n\n不幸的是,这不是一回事。Kotlin 密封类保证在定义它们的文件之外没有给定类的其他实现。这意味着您可以通过仅提供所有可能的替代方案作为案例来耗尽 when 语句(Dart 中的 switch),而不必考虑关于其他地方的潜在子类
\n
虽然dart 语言上对此功能有积极的讨论:代数数据类型,但有一些库可以帮助您实现此行为。您可以使用这个库:
\n\n\n\n\n\n\n\n如果您使用BLoC库,则可以使用此库:
\n\n\n\n希望dart语言尽快添加这个功能
\nDart 3.0 最近引入了它们(在 Flutter 3.10.0 上可用)。完整的文档在这里。
它们特别适合在层之间中继状态(数据 -> 表示和表示 -> 视图)。
好处是每个状态都可以有自己的(不同的)编译时安全的属性。
语法如下:
sealed class Response {}
class Success<Type> extends Response {
final Type data;
Success(this.data);
}
class Failure extends Response {
final Error error;
Failure(this.error);
}
String toString(Response response) => switch (response) {
Success _ => response.data.toString(),
Failure _ => response.error.toString(),
};
String toTypeString(Response response) => switch (response) {
Success _ => 'Success',
Failure _ => 'Failure',
};
Run Code Online (Sandbox Code Playgroud)
您可以使用extends或implements。
当您将类型标记为密封时,编译器会确保打开该类型的值彻底覆盖每个子类型。这使您能够以代数数据类型样式进行编程,并具有您期望的编译时安全性。
| 归档时间: |
|
| 查看次数: |
606 次 |
| 最近记录: |