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

基于Freezed泛型字段过滤Artifact类列表的类型转换问题

解决Freezed泛型Artifact的类型推断与过滤问题

问题根源

核心问题是Dart泛型自动推断将Artifact实例的泛型参数定为Location而非具体的PointLocation/PolygonLocation。因为Location是Freezed联合类型,传入Location.fromPoint()时,Dart默认推断其类型为父类Location,最终生成的实例是_$NewArtifactImpl<Location>,而非期望的_$NewArtifactImpl<PointLocation>。

由于Dart泛型默认是不变的,Artifact<Location>并不是Artifact<PointLocation>的子类型,直接用as Artifact<PointLocation>强制转换会抛出类型不匹配错误。


解决方案

方案1:创建实例时显式指定泛型参数

这是最直接的解决方式,创建Artifact时手动指定泛型类型,确保实例泛型参数为具体的PointLocation或PolygonLocation:

// 创建Point类型Artifact时显式指定泛型
final pointArtifact = Artifact<PointLocation>.yourFactory(
  location: Location.fromPoint(...),
);

// 创建Polygon类型Artifact同理
final polygonArtifact = Artifact<PolygonLocation>.yourFactory(
  location: Location.fromPolygon(...),
);

生成的实例类型为_$NewArtifactImpl<PointLocation>,之后直接用whereType过滤即可:

List<Artifact<PointLocation>> get pointArtifacts => 
    artifacts.whereType<Artifact<PointLocation>>().toList();

方案2:通过Freezed特性安全转换(适用于无法显式指定泛型的场景)

如果实例来自反序列化、第三方数据源等无法手动指定泛型的场景,可利用Freezed的联合类型能力添加安全转换逻辑:

首先在Artifact的Freezed定义中添加自定义方法:

@freezed
class Artifact<T extends Location> with _$Artifact<T> {
  const factory Artifact.typeA({required T location}) = _TypeA<T>;
  const factory Artifact.typeB({required T location}) = _TypeB<T>;

  // 判断是否为Point类型的Artifact
  bool get isPoint => location is PointLocation;

  // 安全转换为Artifact<PointLocation>,失败则返回null
  Artifact<PointLocation>? get toPointArtifact {
    if (location is PointLocation) {
      // 重新构造泛型参数正确的实例
      return when(
        typeA: (loc) => Artifact.typeA(location: loc as PointLocation),
        typeB: (loc) => Artifact.typeB(location: loc as PointLocation),
      );
    }
    return null;
  }
}

过滤时使用:

List<Artifact<PointLocation>> get pointArtifacts => artifacts
    .map((artifact) => artifact.toPointArtifact)
    .whereType<Artifact<PointLocation>>()
    .toList();

这种方式通过重新构造泛型参数正确的实例,避免了不安全的强制类型转换,同时保证类型安全。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 05:11:23