限制泛型函数的类型

huangapple go评论75阅读模式
英文:

Restrict types with generic function

问题

目前我有一个类似这样的类型:

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)
   }
}

我用它来存储不同类型的数字。我在考虑限制允许的类型,像这样:

package hello

type number interface {
   isNumber()
}

type Int32 int32
func (Int32) isNumber(){}

type Float32 float32
func (Float32) isNumber(){}

type object map[string]number

但是我不确定如何像以前那样实现我的add函数。我尝试了相同的函数,但是我得到了这个错误:

cannot use val (variable of type T constrained by any) as type number in assignment:
   T does not implement number (missing isNumber method)

然后我将函数签名更改为:

func add[T number](obj object, key string, val T)

但是我又得到了另一个错误:

cannot use []T{…} (value of type []T) as type number in assignment:
   []T does not implement number (missing isNumber method)

我是否可以做到像我试图做的那样?

英文:

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?

答案1

得分: 2

你可以使用类型约束

type number interface {
~int32 | ~float32
}

而不是创建这样的Float或Int新类型

英文:

You can use type constraints

type number interface {
~int32 | ~float32
}

Instead create such Float or Int new types

答案2

得分: -1

将此添加到问题中的代码中,似乎可以工作:

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]
}

如果有其他选项,请告诉我。

英文:

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.

huangapple
  • 本文由 发表于 2022年3月22日 05:51:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/71564559.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定