Currently I have a type like this:
package hello
type object map[string]any
func add[T any](obj object, key string, val T) {
switch value := obj[key].(type) {
case nil:
obj[key] = val
case T:
obj[key] = []T{value, val}
case []T:
obj[key] = append(value, val)
}
}
which I use to store different types of numbers. I was thinking about restricting the allowed types, like this:
package hello
type number interface {
isNumber()
}
type Int32 int32
func (Int32) isNumber(){}
type Float32 float32
func (Float32) isNumber(){}
type object map[string]number
but I am not sure how to implement my add function as before. I tried the same function, but I get this:
cannot use val (variable of type T constrained by any) as type number in assignment:
T does not implement number (missing isNumber method)
so then I changed the signature to:
func add[T number](obj object, key string, val T)
but I get another error:
cannot use []T{…} (value of type []T) as type number in assignment:
[]T does not implement number (missing isNumber method)
is it possible to do something like what I am trying to do?
CodePudding user response:
You can use type constraints
type number interface {
~int32 | ~float32
}
Instead create such Float or Int new types
CodePudding user response:
Adding this to the code in the question, seems to work:
package main
import "fmt"
type numbers[T any] []T
func (numbers[T]) isNumber(){}
func add[T number](obj object, key string, val T) {
switch value := obj[key].(type) {
case nil:
obj[key] = val
case T:
obj[key] = numbers[T]{value, val}
case numbers[T]:
obj[key] = append(value, val)
}
}
func main() {
obj := object{"alfa": Int32(1), "bravo": Float32(1)}
add(obj, "bravo", Float32(2))
add(obj, "charlie", Int32(1))
fmt.Println(obj) // map[alfa:1 bravo:[1 2] charlie:1]
}
If anyone has others options, let me know.