Home > Enterprise >  Restrict types with generic function
Restrict types with generic function

Time:03-22

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.

  • Related