v2 / vlib / v / tests / generics / generic_interface_test.v
110 lines · 89 sloc · 1.82 KB · ba097c6798022365b25b91e3a039391cfabc7ce1
Raw
1interface Gettable[T] {
2 get() T
3}
4
5struct Animal[T] {
6 metadata T
7}
8
9fn (a Animal[T]) get[T]() T {
10 return a.metadata
11}
12
13// different struct implementing the same interface:
14struct Mineral[T] {
15 value T
16}
17
18fn (m Mineral[T]) get[T]() T {
19 return m.value
20}
21
22////
23
24fn extract[T](xs []Gettable[T]) []T {
25 return xs.map(it.get())
26}
27
28fn extract_basic[T](xs Gettable[T]) T {
29 return xs.get()
30}
31
32fn test_extract() {
33 a := Animal[int]{123}
34 b := Animal[int]{456}
35 c := Mineral[int]{789}
36
37 arr := [Gettable[int](a), Gettable[int](b), Gettable[int](c)]
38 assert typeof(arr).name == '[]Gettable[int]'
39
40 x := extract[int](arr)
41 assert x == [123, 456, 789]
42}
43
44fn test_extract_multiple_instance_types() {
45 a := Animal[string]{'123'}
46 b := Animal[string]{'456'}
47 c := Mineral[string]{'789'}
48
49 arr := [Gettable[string](a), Gettable[string](b), Gettable[string](c)]
50 assert typeof(arr).name == '[]Gettable[string]'
51
52 x := extract[string](arr)
53 assert x == ['123', '456', '789']
54}
55
56fn test_extract_basic() {
57 a := Animal[int]{123}
58 b := Animal[int]{456}
59 c := Mineral[int]{789}
60
61 aa := extract_basic(a)
62 bb := extract_basic(b)
63 cc := extract_basic(c)
64 assert '${aa} | ${bb} | ${cc}' == '123 | 456 | 789'
65}
66
67fn test_extract_basic_multiple_instance_types() {
68 a := Animal[string]{'123'}
69 b := Animal[string]{'456'}
70 c := Mineral[string]{'789'}
71
72 aa := extract_basic(a)
73 bb := extract_basic(b)
74 cc := extract_basic(c)
75 assert '${aa} | ${bb} | ${cc}' == '123 | 456 | 789'
76}
77
78//////
79interface Iterator[T] {
80mut:
81 next() ?T
82}
83
84struct NumberIterator[T] {
85 limit T
86mut:
87 val T
88}
89
90fn (mut i NumberIterator[T]) next[T]() ?T {
91 if i.val >= i.limit {
92 return none
93 }
94 i.val++
95 return i.val
96}
97
98fn test_iterator_implementation() {
99 mut i := Iterator[int](NumberIterator[int]{
100 limit: 10
101 })
102 for {
103 if val := i.next() {
104 println(val)
105 } else {
106 println('iterator is done')
107 break
108 }
109 }
110}
111