Generic Types provide a way to make operations available on different types of objects without having to redefine them.
A method that gets the first element of a list can be written as follows, using a combination of Generic Types and Type Variable Types.
static func getFirst<T>(list: List<T>) -> T = list.get(0)
let list1: List<int> = List(1, 2, 3, 4)
let list2: List<long> = List(1L, 1000L, 1000000L, 1000000000L)
let list3: List<String> = List("a", "b", "c")
let i = getFirst(list1) // type inferred to int
let l = getFirst(list2) // type inferred to long
let s = getFirst(list3) // type inferred to String
The generic type
Listto be passed, be it
List<int>, and adapts the return type of the method accordingly. The type
Listcan be parameterized with another type because it was defined as
interface List<T> extends Collection<T>
Similarly, the type
Map<K, V>can be used with two parameters, for example as
interface Map<K, V>
let map1: Map<String, int> = Map("a": 1, "b": 2)
let map2: Map<int, long> = Map(1: 1000L, 2: 1000000L)
A specialization of Generic Types are Tuple Types. They represent the parameterized class
Tuple.OfX<T1, ..., TX>, where
Xis the number of elements in the Tuple. For example, a variable
let tuple = (1, "a")
Gets its type inferred to be
(int, String), which is syntactic sugar for
dyvil.tuple.Tuple.Of2<int, String>. Tuple Types are covariant, which means that
(int, String)is a subtype of
(any, any), and an expression of the former type can be used where the latter type is required:
let anyTuple: (any, any) = tuple // ok
As of Dyvil v0.31.0, Tuple Types and Expressions are limited to 20 elements.
Another specialization of Generic Types are Function Types. They represent syntactic sugar for parameterized
dyvil.function.Function.OfX<P1, ..., PX, R>types, where
Xis the number of parameters. For example, the function type
(String, int) -> booleanis syntactic sugar for
Function.Of2<String, int, boolean>. The last type argument (in this case
boolean) represents the return type of the function type.
interface Of2<-P1, -P2, +R>
The parameter types are contravariant instead of covariant. This inverts the subtyping relationship, and makes a
Function2<any, any, String>a subtype of
Function2<String, String, any>.