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
|
#### Interface method definitions
|
||||||
|
|
||||||
Also unlike Go, an interface may implement a method.
|
Also unlike Go, an interface can have it's own methods, similar to how
|
||||||
These methods are not implemented by structs which implement that interface.
|
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
|
N.B. This feature is NOT a "default implementation" like in C#.
|
||||||
with the same name as one implemented by this struct, only the method
|
|
||||||
implemented on the interface is called.
|
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
|
```v
|
||||||
struct Cat {}
|
|
||||||
|
|
||||||
fn (c Cat) speak() string {
|
|
||||||
return 'meow!'
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Adoptable {}
|
interface Adoptable {}
|
||||||
|
|
||||||
fn (a Adoptable) speak() string {
|
fn (a Adoptable) speak() string {
|
||||||
return 'adopt me!'
|
return 'adopt me!'
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_adoptable() Adoptable {
|
struct Cat {}
|
||||||
return Cat{}
|
|
||||||
|
fn (c Cat) speak() string {
|
||||||
|
return 'meow!'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Dog {}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
cat := Cat{}
|
cat := Cat{}
|
||||||
assert cat.speak() == 'meow!'
|
assert dump(cat.speak()) == 'meow!'
|
||||||
a := new_adoptable()
|
//
|
||||||
assert a.speak() == 'adopt me!'
|
a := Adoptable(cat)
|
||||||
|
assert dump(a.speak()) == 'adopt me!' // call Adoptable's `speak`
|
||||||
if a is Cat {
|
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