Flutter中能否模仿Dart的FutureOr实现自定义类型联合?
自定义类似FutureOr的联合类型可行吗?
Dart 里的FutureOr<T>是编译器内置的特殊类型,它本质是T和Future<T>的类型联合——也就是说,FutureOr<int>类型的变量可以直接接收int值或者Future<int>对象。现在想模仿这个特性,通过自定义AnimalOr<T>、Animal、Human这几个类,实现一个泛型函数pickCreature<T>():根据条件返回T类型或Animal类型的实例,再把结果赋值给AnimalOr<Human>类型的变量。
用户给出的初始代码示例如下:
abstract class AnimalOr<T> {} abstract class Animal{} abstract class Human{}
AnimalOr<T> pickCreature<T> (){ final result = calculate(); if(conditionIsMet){ return result as T; } return result as Animal; } AnimalOr<Human> creature = pickCreature<Human>();
直接用普通抽象类做不到的原因
首先得明确:FutureOr是Dart编译器专属的语法糖,不是普通抽象类能直接复刻的。你写的普通AnimalOr<T>抽象类,T(比如Human)和Animal都不是它的子类,所以函数里return result as T或者return result as Animal都会直接编译报错——因为T类型实例无法赋值给AnimalOr<T>类型变量,类型不兼容。
可行的实现方案:用密封类模拟联合类型
Dart 3.0及以上支持密封类(sealed class),这是实现自定义联合类型的标准方式。我们可以把AnimalOr<T>定义为密封类,再创建两个子类分别包装T类型和Animal类型的实例:
// 密封类,限制只能有指定的子类 sealed class AnimalOr<T> {} // 包装Animal类型的实例 class AnimalWrapper extends AnimalOr<Never> { final Animal animal; AnimalWrapper(this.animal); } // 包装T类型的实例 class TWrapper<T> extends AnimalOr<T> { final T value; TWrapper(this.value); } // 原有的类定义 abstract class Animal {} abstract class Human implements Animal {} // 根据需求,Human也可以直接继承Animal
然后修改pickCreature函数,返回对应的包装类实例:
// 模拟计算和条件判断 bool conditionIsMet = true; dynamic calculate() => conditionIsMet ? Human() : Animal(); AnimalOr<T> pickCreature<T>() { final result = calculate(); if (conditionIsMet) { return TWrapper<T>(result as T); } return AnimalWrapper(result as Animal); } // 使用示例 void main() { AnimalOr<Human> creature = pickCreature<Human>(); // 用模式匹配处理不同类型 switch (creature) { case TWrapper(value: Human human): print("拿到了Human实例"); break; case AnimalWrapper(animal: Animal animal): print("拿到了Animal实例"); break; } }
这样实现后,AnimalOr<T>就完全具备了“要么是T类型的包装,要么是Animal类型的包装”的联合类型特性,和FutureOr的使用逻辑一致,而且能通过编译器的类型检查。
内容的提问来源于stack exchange,提问作者Sayyid J
相关产品推荐
相关产品推荐

