Skip to content

Instantly share code, notes, and snippets.

@korya
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save korya/f5da5583d2314816ab81 to your computer and use it in GitHub Desktop.
Save korya/f5da5583d2314816ab81 to your computer and use it in GitHub Desktop.
Golang's invariance
/* "Invariance" in golang
* http://play.golang.org/p/ww9UEEKI97
*
* Output:
* > B::foo
* > C::foo
* > B::foo
* > B::bar
* > B::bar
*/
package main
import "fmt"
type B struct{}
func (b *B) bar() {
fmt.Println("B::bar")
}
func (b *B) foo() {
fmt.Println("B::foo")
}
type C struct {
*B
}
func (c *C) foo() {
fmt.Println("C::foo")
}
func callBMethod(h func(*B)) {
b := &B{}
h(b)
}
func callCMethod(h func(*C)) {
c := &C{}
h(c)
}
func main() {
callBMethod((*B).foo)
callCMethod((*C).foo)
bh := (*B).foo
cbh := func(c *C) { bh(c.B) }
callCMethod(cbh)
/* The following statement causes an error:
* ./test.go:37: cannot use (*B).foo (type func(*B)) as type func(*C) in
* argument to callCMethod
*/
//callCMethod((*B).foo)
callBMethod((*B).bar)
callCMethod((*C).bar)
}
/* "Inheritance" in embedded structs
* http://play.golang.org/p/oF3puVgCZk
*
* Output:
* > B::foo
* > C::foo B::foo
* > D::foo C::foo B::foo
*/
package main
import "fmt"
type I interface{
foo()
}
type B struct{}
func (b B) foo() {
fmt.Println("B::foo")
}
type C struct {
B
}
func (c C) foo() {
fmt.Print("C::foo\t")
c.B.foo()
}
type D struct {
C
}
func (d D) foo() {
fmt.Print("D::foo\t")
d.C.foo()
}
func callFooMethod(o I) {
o.foo()
}
func main() {
callFooMethod(&B{})
callFooMethod(&C{})
callFooMethod(&D{})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment