gpt4 book ai didi

Dart 泛型...不是类型错误的子类型

转载 作者:行者123 更新时间:2023-12-03 04:33:39 25 4
gpt4 key购买 nike

class ActivityItem {}

class Activity<T extends ActivityItem> {
T item;

Activity(this.item);
}

class Type1ActivityItem extends ActivityItem {
final String data;

Type1ActivityItem(this.data):super();
}

passType1(Activity<Type1ActivityItem> item) {
print(item);
}

main() {
Activity activity = Activity(Type1ActivityItem('data1'));
print(passType1(activity as Activity<Type1ActivityItem>)); // ERROR
}
在运行时, Dart throw
Uncaught Error :TypeError:“Activity ”的实例:类型“Activity ”不是“Activity ”类型的子类型
当泛型类型信息丢失时有点难以理解
场景一:
  print(Activity(Type1ActivityItem('data1')) is Activity<Type1ActivityItem>);   // True
Dart 能够根据构造函数参数推断泛型类型
场景二:
  Activity activity1 = Activity(Type1ActivityItem('data1'));
print(activity1 is Activity<Type1ActivityItem>); // False
看起来在分配给 activity1 时,通用类型信息丢失了。
场景 3:
  Activity activity2 = Activity<Type1ActivityItem>(Type1ActivityItem('data1'));
print(activity2 is Activity<Type1ActivityItem>); // True
即使分配给activity2,泛型类型仍然存在......

最佳答案

Activity activity = ...


这就是发生错误的原因。这给出了 activity类型 Activity<ActivityItem>这是一种独特的类型,不能向下转换为 Activity<Type1ActivityItem> .
这可以通过几种方式解决:
  • 在构造函数中指定泛型:

  • Activity activity = Activity<Type1ActivityItem>(Type1ActivityItem('data1'));
  • 在类型声明中指定泛型类型:

  • Activity<Type1ActivityItem> activity = Activity(Type1ActivityItem('data1'));
  • 使用类型推断:

  • var activity = Activity(Type1ActivityItem('data1'));
    final activity = Activity(Type1ActivityItem('data1'));
    扩展说明
    class BaseActivityItem {
    final int base = 1;
    }

    class SubActivityItem extends BaseActivityItem {
    final int sub = 2;
    }

    class Activity<T extends BaseActivityItem> {
    T item;

    Activity(this.item);
    }

    passType1(Activity<SubActivityItem> item) {
    print('passType1 received: $item');
    }

    main() {
    // The specified variable type will always be the static type of the variable.
    // Here `Activity` is shorthand for `Activity<BaseActivityItem>`.
    // Activity(SubActivityItem()) is a valid value for `Activity<BaseActivityItem>`.
    Activity activity = Activity(SubActivityItem());
    assert(activity is Activity<BaseActivityItem>);

    // `activity.item` runtime type is, as expected, `SubActivityItem`. But, its
    // interface is limited to `BaseActivityItem`.
    assert(activity.item is SubActivityItem);
    print(activity.item.base); // 1

    // The following will not compile because item has type `BaseActivityItem`.
    //print(activit.item.sub);
    // It can be downcast to `SubActivityItem`.
    print((activity.item as SubActivityItem).sub); // 2

    // `activity`'s runtime type is actually
    // Activity<BaseActivityItem> so casting will fail.
    print(activity is Activity<SubActivityItem>); // false

    print('------------------------------------------------');

    // Here we have another activity with the runtime type of
    // Activity<SubActivityItem>. The actual Activity instance
    // is a Activity<SubActivityItem>, but its interface is
    // limited by `Activity` i.e. `Activity<BaseActivityItem>`.
    Activity subRuntimeType = Activity<SubActivityItem>(SubActivityItem());
    assert(subRuntimeType is Activity<BaseActivityItem>);
    assert(subRuntimeType is Activity<SubActivityItem>);
    print(subRuntimeType.item.base); // 1

    // This will fail to compile because item's interface is
    // BaseActivityItem.
    //print(subRuntimeType.item.sub);
    // However it can be downcast:
    print((subRuntimeType.item as SubActivityItem).sub); // 2
    print((subRuntimeType as Activity<SubActivityItem>).item.sub); // 2

    // This can be properly passed to `passType1` because dart knows
    // that `subRuntimeType` is an Activity<SubActivityItem>.
    passType1(subRuntimeType);

    print('------------------------------------------------');

    // The constructor will return the correct type.
    Activity<SubActivityItem> subType = Activity(SubActivityItem());
    // The following will fail to compile as the constructor return value
    // is not valid for variable type:
    //... subType = Activity(BaseActivityItem());
    //... subType = Activity<BaseActivityItem>(SubActivityItem());
    assert(subType is Activity);
    assert(subType is Activity<SubActivityItem>);
    print(subType.item.base); // 1
    print(subType.item.sub); // 2
    passType1(subType);

    print('------------------------------------------------');

    // These will infer the type from rhs:
    var inferVarType = Activity(SubActivityItem());
    final inferFinalType = Activity(SubActivityItem());
    print(inferVarType.item.sub); // 2
    print(inferFinalType.item.sub); // 2
    passType1(inferVarType);
    passType1(inferFinalType);
    }

    关于Dart 泛型...不是类型错误的子类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64505356/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com