限制泛型函数的类型

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

Restrict types with generic function

问题

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

  1. package hello
  2. type object map[string]any
  3. func add[T any](obj object, key string, val T) {
  4. switch value := obj[key].(type) {
  5. case nil:
  6. obj[key] = val
  7. case T:
  8. obj[key] = []T{value, val}
  9. case []T:
  10. obj[key] = append(value, val)
  11. }
  12. }

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

  1. package hello
  2. type number interface {
  3. isNumber()
  4. }
  5. type Int32 int32
  6. func (Int32) isNumber(){}
  7. type Float32 float32
  8. func (Float32) isNumber(){}
  9. type object map[string]number

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

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

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

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

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

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

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

英文:

Currently I have a type like this:

  1. package hello
  2. type object map[string]any
  3. func add[T any](obj object, key string, val T) {
  4. switch value := obj[key].(type) {
  5. case nil:
  6. obj[key] = val
  7. case T:
  8. obj[key] = []T{value, val}
  9. case []T:
  10. obj[key] = append(value, val)
  11. }
  12. }

which I use to store different types of numbers. I was thinking about
restricting the allowed types, like this:

  1. package hello
  2. type number interface {
  3. isNumber()
  4. }
  5. type Int32 int32
  6. func (Int32) isNumber(){}
  7. type Float32 float32
  8. func (Float32) isNumber(){}
  9. 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:

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

so then I changed the signature to:

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

but I get another error:

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

is it possible to do something like what I am trying to do?

答案1

得分: 2

你可以使用类型约束

  1. type number interface {
  2. ~int32 | ~float32
  3. }

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

英文:

You can use type constraints

  1. type number interface {
  2. ~int32 | ~float32
  3. }

Instead create such Float or Int new types

答案2

得分: -1

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

  1. package main
  2. import "fmt"
  3. type numbers[T any] []T
  4. func (numbers[T]) isNumber(){}
  5. func add[T number](obj object, key string, val T) {
  6. switch value := obj[key].(type) {
  7. case nil:
  8. obj[key] = val
  9. case T:
  10. obj[key] = numbers[T]{value, val}
  11. case numbers[T]:
  12. obj[key] = append(value, val)
  13. }
  14. }
  15. func main() {
  16. obj := object{"alfa": Int32(1), "bravo": Float32(1)}
  17. add(obj, "bravo", Float32(2))
  18. add(obj, "charlie", Int32(1))
  19. fmt.Println(obj) // map[alfa:1 bravo:[1 2] charlie:1]
  20. }

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

英文:

Adding this to the code in the question, seems to work:

  1. package main
  2. import "fmt"
  3. type numbers[T any] []T
  4. func (numbers[T]) isNumber(){}
  5. func add[T number](obj object, key string, val T) {
  6. switch value := obj[key].(type) {
  7. case nil:
  8. obj[key] = val
  9. case T:
  10. obj[key] = numbers[T]{value, val}
  11. case numbers[T]:
  12. obj[key] = append(value, val)
  13. }
  14. }
  15. func main() {
  16. obj := object{"alfa": Int32(1), "bravo": Float32(1)}
  17. add(obj, "bravo", Float32(2))
  18. add(obj, "charlie", Int32(1))
  19. fmt.Println(obj) // map[alfa:1 bravo:[1 2] charlie:1]
  20. }

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:

确定