Generics
For Dart see here. For Kotlin see here
The syntax for creating and using classes with type parameters is the same
Generics are reified
In Dart generic types are reified, which means that they carry their type information around at runtime.
In Kotlin, like in Java, generics use type erasure, which means that generic type parameters are removed at runtime: you can test whether an object is a List
, but you can’t test whether it’s a List<String>
. But there is a work-around, that is inline functions with reified type parameters
Generic types In collections
Kotlin
// note: the explicit type parameter here is actually redundant
var names = mutableListOf<String>("Seth", "Kathy", "Lars")
// note: the explicit type parameter here is actually redundant
var uniqueNames = mutableSetOf<String>("Seth", "Kathy", "Lars")
// note: the explicit type parameter here is actually redundant
var pages = mutableMapOf<String, String>(
"index.html" to "Homepage",
"robots.txt" to "Hints for web robots",
"humans.txt" to "We are people, not machines"
)
Dart
//define a List<String>
// note: the explicit type parameter here is actually redundant
var names = <String>['Seth', 'Kathy', 'Lars'];
//define a Set<String>
// note: the explicit type parameter here is actually redundant
var uniqueNames = <String>{'Seth', 'Kathy', 'Lars'};
//define a Map<String,String>
// note: the explicit type parameter here is actually redundant
var pages = <String, String>{
'index.html': 'Homepage',
'robots.txt': 'Hints for web robots',
'humans.txt': 'We are people, not machines'
};
}
Restricting the generic type
Kotlin
interface Animal
class Dog(var name:String):Animal
class Cat(var name:String):Animal
//a pair of any objects that derive from the Animal base class
class PairOfAnimals<A : Animal>(var first:A, var second:A)
var p1 = PairOfAnimals(Dog("Pluto"),Dog("Max")) //ok
var p2 = PairOfAnimals(Dog("Pluto"),Cat("Felix")) //ok
var p3 = PairOfAnimals(Cat("Tom"),Cat("Felix")) //ok
//compilation error! String is not an Animal
var p4 = PairOfAnimals("aa",Cat("Felix"))
Dart
class Animal {}
class Dog implements Animal {
String name;
Dog(this.name);
}
class Cat implements Animal {
String name;
Cat(this.name);
}
//a pair of any objects that derive from the Animal base class
class PairOfAnimals<A extends Animal> {
A first,second;
PairOfAnimals(this.first,this.second);
}
var p1 = PairOfAnimals(Dog("Pluto"),Dog("Max")); //ok
var p2 = PairOfAnimals(Dog("Pluto"),Cat("Felix")); //ok
var p3 = PairOfAnimals(Cat("Tom"),Cat("Felix")); //ok
//compilation error! String is not an Animal
var p4 = PairOfAnimals("aa",Cat("Felix"));
Handling bounds on generic type can be much more complex in Kotlin
see Kotlin docs
Restricting to non-nullable type
Kotlin
// only non nullable type parameters allowed
// (Any is base type of all non-nullable types)
class SomeClass<T:Any>
Dart
// only non-nullable type parameters allowed
// (Object is base type of all non-nullable types)
class SomeClass<T extends Object>
Instantiating generic class with no type parameter
In Dart it is possible to instantiate a generic class without specifying the type parameter.
Dart
class SomeBaseType {}
class SomeClass<T extends SomeBaseType> {}
var foo = SomeClass(); //instance of SomeClass<SomeBaseType>