You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dart多泛型Result模式if语句类型判断问题求助

Dart/Flutter 双泛型Result密封类的类型推断问题解析

为什么switch能用,if却不行?

这本质是Dart编译器的类型推断规则差异导致的:

  • 密封类的switch分支要求穷尽所有可能,编译器能完全确定每个分支对应的具体子类,哪怕你用void忽略某个泛型参数,它也能精准匹配到SuccessResult或ErrorResult的具体实例,所以不用转换就能直接访问字段。
  • 但if语句的类型推断保守得多,尤其是当Result带双泛型参数时,哪怕你用is判断了类型,编译器没法确定这个SuccessResult的泛型参数具体是什么(比如你声明的是Result<void, MyError>,编译器没法自动把它和SuccessResult<void, MyError>划等号),所以不会自动提升类型,必须显式转换才能访问字段。

怎么解决?

1. 给泛型参数设默认值,减少冗余声明

给Result的两个泛型参数都设默认值void,这样使用时只需要指定你需要的那个泛型,编译器能更清晰地推断类型:

sealed class Result<S = void, E = void> {}

class SuccessResult<S, E> extends Result<S, E> {
  final S result;
  SuccessResult(this.result);
}

class ErrorResult<S, E> extends Result<S, E> {
  final E error;
  ErrorResult(this.error);
}

使用示例:

// 成功结果,只指定S泛型,E用默认void
final success = SuccessResult<String>('加载完成');
// 错误结果,只指定E泛型,S用默认void
final error = ErrorResult<Exception>(Exception('加载失败'));

2. if判断里显式类型转换

最简单直接的方式,在if判断后用as把Result转成具体子类,就能直接访问字段:

Result<String, Exception> result = SuccessResult('hello');

if (result is SuccessResult<String, Exception>) {
  print((result as SuccessResult<String, Exception>).result);
}

3. 用扩展方法封装类型检查

给Result加个扩展方法,把类型检查和转换封装起来,代码更干净:

extension ResultHelper<S, E> on Result<S, E> {
  bool get isSuccess => this is SuccessResult<S, E>;
  bool get isError => this is ErrorResult<S, E>;

  SuccessResult<S, E>? get success => isSuccess ? this as SuccessResult<S, E> : null;
  ErrorResult<S, E>? get failure => isError ? this as ErrorResult<S, E> : null;
}

使用示例:

final result = SuccessResult('test data');
if (result.isSuccess) {
  print(result.success?.result);
}

4. Dart 3.0+用模式匹配(最推荐)

如果你的项目用Dart 3.0及以上版本,直接用模式匹配,编译器会自动推断类型,不用手动转换:

Result<String, Exception> result = SuccessResult('加载成功');

// 匹配成功结果,直接获取result字段
if (result case SuccessResult(:final result)) {
  print(result);
}

// 匹配错误结果,直接获取error字段
if (result case ErrorResult(:final error)) {
  print(error.toString());
}

内容的提问来源于stack exchange,提问作者asci

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 16:57:12