Problems understanding usage of `interface{}` in Go -
i'm trying port algorithm python go. central part of tree built using dicts, should stay way since each node can have arbitrary number of children. leaves @ same level, the lowest level dicts contain other dicts, while lowest level ones contain floats. this:
tree = {} insert(tree, ['a', 'b'], 1.0) print tree['a']['b'] so while trying port code go while learning language @ same time, started test basic idea:
func main() { tree := make(map[string]interface{}) tree["a"] = make(map[string]float32) tree["a"].(map[string]float32)["b"] = 1.0 fmt.println(tree["a"].(map[string]float32)["b"]) } this works expected, next step turn routine take "tree", path, , value. chose recursive approach , came this:
func insert(tree map[string]interface{}, path []string, value float32) { node := path[0] l := len(path) switch { case l > 1: if _, ok := tree[node]; !ok { if l > 2 { tree[node] = make(map[string]interface{}) } else { tree[node] = make(map[string]float32) } } insert(tree[node], path[1:], value) //recursion case l == 1: leaf := tree leaf[node] = value } } this how imagine routine should structured, can't line marked "recursion" work. there either compiler error, or runtime error if try perform type assertion on tree[node]. correct way this?
go perhaps not ideal solution generic data structures this. type assertions make possible, manipulating data in requires more work used python , other scripting languages.
about specific issue: missing type assertion in insert() call. value of tree[node] of type interface{} @ point. function expects type map[string]interface{}. type assertion solve that.
here's working example:
package main import "fmt" type tree map[string]interface{} func main() { t := make(tree) insert(t, []string{"a", "b"}, 1.0) v := t["a"].(tree)["b"] fmt.printf("%t %v\n", v, v) // prints: float32 1 } func insert(tree tree, path []string, value float32) { node := path[0] len := len(path) switch { case len == 1: tree[node] = value case len > 1: if _, ok := tree[node]; !ok { tree[node] = make(tree) } insert(tree[node].(tree), path[1:], value) //recursion } } note created new type map. makes code little easier follow. use same 'map[string]interface{}` both tree nodes , leaves. if want float out of resulting tree, type assertion needed:
leaf := t["a"].(tree)["b"] // leaf of type 'interface{}`. val := leaf.(float32)
Comments
Post a Comment