Everything negative-pressure,challenges-is all an opportunity for me to rise
11 September 2020
这篇文章讨论一下Dart中的泛型中的协变(covariant)
熟悉Java的人都知道,泛型类型在Java是不变(invariant)的,这意味这List<Cat>
并不是List<Animal>
的子类。比如以下代码在Java中会在编译期报错(Cat是Animal的子类):
1
2
List<Cat> cats = new ArrayList<>();
List<Animal> animals = cats; // error
需要让此类型发生协变(covariant):
1
2
List<Cat> cats = new ArrayList<>();
List<? extends Animal> animals = cats; // correct
但在Dart中,List<Cat>
是List<Animal>
的子类,这意味这以下代码是正常运行的:
1
List<Animal> animals = <Cat>[];
我们此时在定义一个Animal的子类-Dog,我们往animals
添加一只Dog:
1
animals.add(Dog());
以上代码在编译期通过,但是在运行时会发生错误:
1
2
3
4
5
6
Unhandled exception:
type 'Dog' is not a subtype of type 'Cat' of 'value'
#0 List.add (dart:core-patch/growable_array.dart)
#1 main (file:///home/xianxueliang/IdeaProjects/dart_app/bin/dart_app.dart:11:12)
#2 _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:299:32)
#3 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)
Dart语言的泛型系统没有Java语言那么完善,协变(covariant)(关键字covariant)在Dart中也比较脊肋,限制也比较多,也没有逆变一说,所以在进行程序设计的时候需要格外注意。
1
2
3
4
5
6
7
8
9
10
11
12
13
abstract class Animal {
void chase(covariant Animal animal);
}
class Cat extends Animal {
@override
void chase(Cat animal) {}
}
class Dog extends Animal {
@override
void chase(Dog animal) {}
}
— Lenox Xian