| 1 | interface Animal { |
| 2 | mut: |
| 3 | breed string |
| 4 | } |
| 5 | |
| 6 | struct Cat { |
| 7 | padding int // ensures that the field offsets can be different |
| 8 | mut: |
| 9 | breed string |
| 10 | } |
| 11 | |
| 12 | struct Dog { |
| 13 | padding [256]u8 |
| 14 | padding2 int |
| 15 | mut: |
| 16 | breed string |
| 17 | } |
| 18 | |
| 19 | fn use_interface(a Animal) { |
| 20 | assert a.breed in ['Persian', 'Labrador'] |
| 21 | if a is Cat { |
| 22 | assert a.breed == 'Persian' |
| 23 | } else { |
| 24 | assert a.breed == 'Labrador' |
| 25 | } |
| 26 | } |
| 27 | |
| 28 | fn mutate_interface(mut a Animal) { |
| 29 | if mut a is Cat { |
| 30 | a.breed = 'Siamese' |
| 31 | } else { |
| 32 | a.breed = 'Golden Retriever' |
| 33 | } |
| 34 | if mut a is Cat { |
| 35 | assert a.breed == 'Siamese' |
| 36 | } else { |
| 37 | assert a.breed == 'Golden Retriever' |
| 38 | } |
| 39 | a.breed = 'what??' |
| 40 | assert a.breed == 'what??' |
| 41 | } |
| 42 | |
| 43 | fn test_interface_fields() { |
| 44 | mut c := Cat{ |
| 45 | breed: 'Persian' |
| 46 | } |
| 47 | mut d := Dog{ |
| 48 | breed: 'Labrador' |
| 49 | } |
| 50 | use_interface(c) |
| 51 | use_interface(d) |
| 52 | mutate_interface(mut c) |
| 53 | mutate_interface(mut d) |
| 54 | assert c.breed == 'what??' |
| 55 | assert d.breed == 'what??' |
| 56 | } |
| 57 | |
| 58 | struct Nofun { |
| 59 | foo fn (int) int |
| 60 | } |
| 61 | |
| 62 | interface NofunInterface { |
| 63 | foo fn (int) int |
| 64 | } |
| 65 | |
| 66 | fn my_fn(a int) int { |
| 67 | assert a == 123 |
| 68 | return a * 2 |
| 69 | } |
| 70 | |
| 71 | fn test_interface_fn_pointer_fields() { |
| 72 | nf := NofunInterface(Nofun{my_fn}) |
| 73 | assert nf.foo(123) == 246 |
| 74 | } |
| 75 | |
| 76 | // For issue: 16198 errors when the reference interface type field of the struct is nil(init, assign...) |
| 77 | interface Speaker { |
| 78 | speak() string |
| 79 | } |
| 80 | |
| 81 | struct Wolf {} |
| 82 | |
| 83 | fn (w Wolf) speak() string { |
| 84 | return 'woof' |
| 85 | } |
| 86 | |
| 87 | struct Foo { |
| 88 | mut: |
| 89 | speaker &Speaker = unsafe { nil } |
| 90 | } |
| 91 | |
| 92 | fn test_set_nil_to_ref_interface_type_fields() { |
| 93 | mut foo := Foo{ |
| 94 | speaker: unsafe { nil } |
| 95 | } |
| 96 | assert true |
| 97 | |
| 98 | foo.speaker = unsafe { nil } |
| 99 | assert true |
| 100 | |
| 101 | foo.speaker = &Wolf{} |
| 102 | assert foo.speaker.speak() == 'woof' |
| 103 | } |
| 104 | |