I’m new to Go and learning by translating a C++ program I have into Go.
The problem is that I have a graph with many types of nodes. In C++ this involves a base class and other classes built from that, along with coercing pointers to the base class into the correct node type.
My understanding is that I can do this in Go with interfaces and conversions. What I have so far (simplified) is
type Base struct{
id int
up int
}
type Node struct{
Base
left,right,down int
}
type Leaf struct{
Base
val string
}
//and this is just a huge guess that doesn't work
type NodeIf interface{
Node
}
type LeafIf interface{
Leaf
}
func myfunc( vec []Base, a int){
if n,ok := vec[a](NodeIf); ok{
//do something with n as a Node
}else{
//gack! panic
}
}
The question is, hopefully, how do I make an interface that says something is a struct of a certain type?
An interface in Go means “the type has methods specified in the interface”. I tried to recreate your example to show how this could be done. Since the structs don’t share any methods already, I defined an interface with a dummy one and implemented it for Base.
package main
import "fmt"
type Base struct {
id int
up int
}
// This will satisfy the `Based` interface defined below for all structs that embed Base.
func (b Base) Dummy() {}
type Node struct {
Base
left, right, down int
}
type Leaf struct {
Base
val string
}
type Based interface {
Dummy()
}
func myfunc(vec []Based, a int) error {
val := vec[a]
switch val.(type) {
case Node:
fmt.Println("Doing something with Node")
default:
return fmt.Errorf("gack! unexpected type %T", val)
}
return nil
}
func main() {
vec := []Based{
Node{},
Leaf{},
Node{},
Node{},
}
err := myfunc(vec, 3)
fmt.Println("returned error:", err)
err = myfunc(vec, 1)
fmt.Println("returned error:", err)
}
Thank you. Now I understand a lot more about interfaces. The bit of brilliance is that variables declared with a specific interface can then be used in the val.(type) or val.(some-type-that-meets-the-interface) constructs.