100 lines
1.6 KiB
V
100 lines
1.6 KiB
V
interface Gettable<T> {
|
|
get() T
|
|
}
|
|
|
|
struct Animal<T> {
|
|
metadata T
|
|
}
|
|
|
|
fn (a Animal<T>) get<T>() T {
|
|
return a.metadata
|
|
}
|
|
|
|
// different struct implementing the same interface:
|
|
struct Mineral<T> {
|
|
value T
|
|
}
|
|
|
|
fn (m Mineral<T>) get<T>() T {
|
|
return m.value
|
|
}
|
|
|
|
////
|
|
|
|
fn extract<T>(xs []Gettable<T>) []T {
|
|
return xs.map(it.get())
|
|
}
|
|
|
|
fn extract_basic<T>(xs Gettable<T>) T {
|
|
return xs.get()
|
|
}
|
|
|
|
fn test_extract() {
|
|
a := Animal<int>{123}
|
|
b := Animal<int>{456}
|
|
c := Mineral<int>{789}
|
|
|
|
arr := [Gettable<int>(a), Gettable<int>(b), Gettable<int>(c)]
|
|
assert typeof(arr).name == '[]Gettable<int>'
|
|
|
|
x := extract<int>(arr)
|
|
assert x == [123, 456, 789]
|
|
}
|
|
|
|
// fn test_extract_multiple_instance_types() {
|
|
// a := Animal<string>{'123'}
|
|
// b := Animal<string>{'456'}
|
|
// c := Mineral<string>{'789'}
|
|
|
|
// arr := [Gettable<string>(a), Gettable<string>(b), Gettable<string>(c)]
|
|
// assert typeof(arr).name == '[]Gettable<string>'
|
|
|
|
// x := extract<string>(arr)
|
|
// assert x == ['123', '456', '789']
|
|
// }
|
|
|
|
fn test_extract_basic() {
|
|
a := Animal<int>{123}
|
|
b := Animal<int>{456}
|
|
c := Mineral<int>{789}
|
|
|
|
aa := extract_basic(a)
|
|
bb := extract_basic(b)
|
|
cc := extract_basic(c)
|
|
assert '$aa | $bb | $cc' == '123 | 456 | 789'
|
|
}
|
|
|
|
//////
|
|
interface Iterator<T> {
|
|
mut:
|
|
next() ?T
|
|
}
|
|
|
|
struct NumberIterator<T> {
|
|
limit T
|
|
mut:
|
|
val T
|
|
}
|
|
|
|
fn (mut i NumberIterator<T>) next<T>() ?T {
|
|
if i.val >= i.limit {
|
|
return none
|
|
}
|
|
i.val++
|
|
return i.val
|
|
}
|
|
|
|
fn test_iterator_implementation() {
|
|
mut i := Iterator<int>(NumberIterator<int>{
|
|
limit: 10
|
|
})
|
|
for {
|
|
if val := i.next() {
|
|
println(val)
|
|
} else {
|
|
println('iterator is done')
|
|
break
|
|
}
|
|
}
|
|
}
|