Currently I am using some code like this:
package hello
type object map[string]interface{}
func (o object) get(key string) object {
val, _ := o[key].(object)
return val
}
func (o object) getInt(key string) int {
val, _ := o[key].(int)
return val
}
but the issue is, I have to write a function for every type I want to return. I tried using something like this:
package hello
type object map[string]interface{}
// syntax error: method must have no type parameters
func (o object) get[T object|int](key string) T {
val, _ := o[key].(T)
return val
}
then I did this:
package hello
type object map[string]interface{}
type token[T object|int] struct {
in object
out T
}
func (t token[T]) get(key string) token[T] {
t.out, _ = t.in[key].(T)
return t
}
which compiles, but since in
never gets updated, I don't think I could do chaining, for a nested map:
something.get("one").get("two").get("three")
Is it possible to do something with generics, to give a similar result to my original code, but without having the copy paste functions?
I think I figured it out. You can create a wrapper type, that holds the current object, as well as the output value. If anyone has other ideas, I am interested in them as well:
package main
type object map[string]interface{}
type token[T any] struct {
object
value T
}
func newToken[T any](m object) token[T] {
return token[T]{object: m}
}
func (t token[T]) get(key string) token[T] {
switch val := t.object[key].(type) {
case object:
t.object = val
case T:
t.value = val
}
return t
}
Example:
package main
func main() {
obj := object{
"one": object{
"two": object{"three": 3},
},
}
three := newToken[int](obj).get("one").get("two").get("three")
println(three.value == 3)
}