作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
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
print(Activity(Type1ActivityItem('data1')) is Activity<Type1ActivityItem>); // True
Dart 能够根据构造函数参数推断泛型类型
Activity activity1 = Activity(Type1ActivityItem('data1'));
print(activity1 is Activity<Type1ActivityItem>); // False
看起来在分配给 activity1 时,通用类型信息丢失了。
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/
我是一名优秀的程序员,十分优秀!