docs: clarify the interface methods section
parent
db50e79d26
commit
310969a057
48
doc/docs.md
48
doc/docs.md
|
@ -2789,38 +2789,52 @@ For more information, see [Dynamic casts](#dynamic-casts).
|
|||
|
||||
#### Interface method definitions
|
||||
|
||||
Also unlike Go, an interface may implement a method.
|
||||
These methods are not implemented by structs which implement that interface.
|
||||
Also unlike Go, an interface can have it's own methods, similar to how
|
||||
structs can have their methods. These 'interface methods' do not have
|
||||
to be implemented, by structs which implement that interface.
|
||||
They are just a convenient way to write `i.some_function()` instead of
|
||||
`some_function(i)`, similar to how struct methods can be looked at, as
|
||||
a convenience for writing `s.xyz()` instead of `xyz(s)`.
|
||||
|
||||
When a struct is wrapped in an interface that has implemented a method
|
||||
with the same name as one implemented by this struct, only the method
|
||||
implemented on the interface is called.
|
||||
N.B. This feature is NOT a "default implementation" like in C#.
|
||||
|
||||
For example, if a struct `cat` is wrapped in an interface `a`, that has
|
||||
implemented a method with the same name `speak`, as a method implemented by
|
||||
the struct, and you do `a.speak()`, *only* the interface method is called:
|
||||
|
||||
```v
|
||||
struct Cat {}
|
||||
|
||||
fn (c Cat) speak() string {
|
||||
return 'meow!'
|
||||
}
|
||||
|
||||
interface Adoptable {}
|
||||
|
||||
fn (a Adoptable) speak() string {
|
||||
return 'adopt me!'
|
||||
}
|
||||
|
||||
fn new_adoptable() Adoptable {
|
||||
return Cat{}
|
||||
struct Cat {}
|
||||
|
||||
fn (c Cat) speak() string {
|
||||
return 'meow!'
|
||||
}
|
||||
|
||||
struct Dog {}
|
||||
|
||||
fn main() {
|
||||
cat := Cat{}
|
||||
assert cat.speak() == 'meow!'
|
||||
a := new_adoptable()
|
||||
assert a.speak() == 'adopt me!'
|
||||
assert dump(cat.speak()) == 'meow!'
|
||||
//
|
||||
a := Adoptable(cat)
|
||||
assert dump(a.speak()) == 'adopt me!' // call Adoptable's `speak`
|
||||
if a is Cat {
|
||||
println(a.speak()) // meow!
|
||||
// Inside this `if` however, V knows that `a` is not just any
|
||||
// kind of Adoptable, but actually a Cat, so it will use the
|
||||
// Cat `speak`, NOT the Adoptable `speak`:
|
||||
dump(a.speak()) // meow!
|
||||
}
|
||||
//
|
||||
b := Adoptable(Dog{})
|
||||
assert dump(b.speak()) == 'adopt me!' // call Adoptable's `speak`
|
||||
// if b is Dog {
|
||||
// dump(b.speak()) // error: unknown method or field: Dog.speak
|
||||
// }
|
||||
}
|
||||
```
|
||||
|
||||
|
|
Loading…
Reference in New Issue