Skip to content

Instantly share code, notes, and snippets.

@mt-inside
Last active December 17, 2020 16:06
Show Gist options
  • Save mt-inside/5900c96655649e06add9209c7e4521f1 to your computer and use it in GitHub Desktop.
Save mt-inside/5900c96655649e06add9209c7e4521f1 to your computer and use it in GitHub Desktop.
A tour of interfaces and type assertions.
type Foo interface {
GetA() int
}
type Bar interface {
GetA() int
GetB() string
}
type lol struct {
x int
}
type rofl struct {
x int
y float64
}
func (self lol) GetA() int {
return self.x
}
func (self lol) GetB() string {
return strconv.Itoa(self.x)
}
func main() {
f := Foo(lol{5})
b := Bar(lol{5})
fmt.Printf("%d\n", f.GetA())
fmt.Printf("%s\n", b.GetB())
/* Iface -> struct */
// needs type assertion, becuase this Foo might not be wrapping a lol
// other structs might satisfy Foo
var l lol
l = f.(lol)
fmt.Printf("%d\n", l.x)
/* struct -> iface */
// just works, as the compiler can see there's a GetA() that recieves lo
// ifaces aren't really involved here at all, because method implimentat
l1 := lol{5}
fmt.Printf("%d\n", l1.GetA())
/* iface -> iface */
// this is what you commonly see in the wild
// I have a thing typed as one iface, and I want to use it as another if
// need a type assertion here, as there could be >1 structs satisfying F
// "this type quacks like a Foo, but does is also quack like a Bar?"
var b1 Bar
b1 = f.(Bar)
fmt.Printf("%s\n", b1.GetB())
// don't need a type assertion for this degenerate case, as I guess the
// my ifaces are defined explicity, but this is what you'd get with ifac
var f1 Foo
f1 = b
fmt.Printf("%d\n", f1.GetA())
/* struct -> struct */
// var r rofl
// r = l.(rofl) - can't do this; "non-interface type on left"
/* type assertions */
// both of these match, just change the other to see the other
// NB: one is a struct and one is an interface; these branches do pretty different things with the same syntax
switch x := f.(type) {
case Bar:
fmt.Printf("f's wrapped struct also satisfies Bar: %s\n", x.GetB
case lol:
fmt.Printf("f wraps a lol: %d\n", x.x)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment