I've been working in an interface to use as a hierarchical tree. The idea is to aloud the concrete implementations to call .Children()
, .Father()
and a function to auto populate the hierarchy based on a slice of {id, FatherId}
schema.
I only need three different implementations of this interface, maybe it's more convenient to do the whole thing for each struct but I'm new to Go and decided to use this example to understand interfaces.
I've come to an interface that looks something like this:
type Node interface{
Equals(nodo *Node) bool
AddChild(child *Node)
SetFather(father *Node)
Children() []Node
Father() *Node
}
So the idea is call a Populate
function:
func Populate(plainNodes []Node, HierarchichalNodes *[]Node) {}
Plain nodes would be items defining the id of his father:
{id: "Animal", father: ""}
{id: "Plant", father: ""}
{id: "Mammals", father: "Animal"}
Hierarchical nodes would be the result:
Animal
|__Mammals
Plant
The problem I'm getting is when I try to implement the interface in a concrete struct, this case "Category"
.
type Category struct{
children []Category
father Category
}
func (c Category) SetFather(node *Node) {
v, ok = node.(*Category)
c.father = v
}
Notice that in Category
I want to work with Category
father and children, not with interface Node
.
I can't do the conversion, I get :
invalid type assertion: nodo.(*Category) (non-interface type *Node on left)
Any ideas?
yourbasic.org/golang A type assertion provides access to an interface’s concrete value. Type assertions Type switches Type assertions A type assertiondoesn’t really convert an interfaceto another data type, but it provides access to an interface’s concrete value, which is typically what you want.
Pointers Initialization in Go The pointers of a type are initialized using the address-of (&) operator on a subject of that specific type. Here is the way to do it. 4. Go Pointers dereferencing Dereferencing a pointer means getting the value inside the address the pointer holds.
A pointer is a variable that stores the address it points to. A pointer of a specific type can only point to that type. 2. GoLang Pointer syntax The syntax for the pointers is really simple.
Type assertions allow us to access the data and data type of values stored by the interface. Before we learn about type assertions, let's see why we need type assertions in Go. We know that an empty interface can accept any type and number of values. For example,
Your parameter is node *Node
, it is of type *Node
. Node
is an interface type, but *Node
is not: it is a pointer to interface.
Don't use pointer to interface, it is very rarely needed. Instead change it to node Node
. Also change all your other *Node
pointers to just Node
.
Also if Category.SetFather()
method intends to change the Category
value identified as the receiver, it must be a pointer else you'd only end up changing a copy which will be discarded after SetFather()
returns. So use a receiver like c *Category
.
Going further, if the node
argument contains a *Category
wrapped in an interface, you can't directly assign it to Category.father
as that is a non-pointer type Category
. You need a pointer indirection, e.g. c.father = *v
; or change the type of the father
field to be a pointer: father *Category
.
Corrected SetFather()
method could look like this:
func (c *Category) SetFather(node Node) {
if v, ok := node.(*Category); ok {
c.father = *v
}
}
This should work:
(*nodo).(Category)
De-reference first, assert afterwards.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With