Skip to content

Instantly share code, notes, and snippets.

@smallnest
Forked from strickyak/gist:4201971
Created January 5, 2020 16:04
Show Gist options
  • Select an option

  • Save smallnest/2bf9473c8fa9b66f4d32dd6087d94021 to your computer and use it in GitHub Desktop.

Select an option

Save smallnest/2bf9473c8fa9b66f4d32dd6087d94021 to your computer and use it in GitHub Desktop.
How to simulate classes and virtual methods in Golang.
/*
How to simulate classes and virtual methods in Go.
*/
package main
import . "fmt"
type A struct {
// Set My to outermost object (most derived class) after constructing.
// To call virtual functions, cast My to an interface containing the method you want.
My interface{}
a int
}
func (me *A) F() int {
return me.My.(VirtA).M() + 1000
}
func (me *A) tryG() int {
bp, ok := me.My.(VirtB)
if ok {
return bp.G()
}
return -1 // because conversion failed.
}
func (me *A) M() int {
return me.a * me.a
}
type B struct {
A // embed the "superclass"
b int
}
func (me* B) super() *A { return &me.A }
func (me *B) G() int {
return me.My.(VirtA).M() + 2000
}
func (me *B) M() int {
return me.a * me.a * me.a
}
type C struct {
B // embed the "superclass"
}
func (me* C) super() *B { return &me.B }
func (me *C) G() int {
return me.My.(VirtA).M() + 10 * me.super().G()
}
// For convenience, we define a VirtX interface for each class X.
// We could also define an interface for each method.
type VirtA interface {
F() int
M() int
}
type VirtB interface {
VirtA // embed the "superclass" interface
G() int
}
type VirtC interface {
VirtB // embed the "superclass" interface
}
func main() {
var aa *A = &A{nil, 2}
aa.My = aa // Set instance of A with A*
Printf("hello, world\n")
Printf("aa.F %d\n", aa.F())
Printf("aa.M %d\n", aa.M())
Printf("aa.tryG %d\n", aa.tryG())
var bb *B = &B{A{nil, 2}, 3}
bb.My = bb // Set instance of B with B*
Printf("bb.F %d\n", bb.F())
Printf("bb.M %d\n", bb.M())
Printf("bb.tryG %d\n", bb.tryG())
var cc *C = &C{B{A{nil, 2}, 3}}
cc.My = cc // Set instance of C with C*
Printf("cc.F %d\n", cc.F())
Printf("cc.M %d\n", cc.M())
Printf("cc.tryG %d\n", cc.tryG())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment