想象一下我有以下结构:
type MyGeneric[T string | int] struct {
}
我想在创建新的 MyGeneric 时检查用于实例化该结构的泛型是字符串还是 int。
myGenericString := MyGeneric[string]{}
myGenericString.canHandle("hello") -> should return true
myGenericString.canHandle(8) -> should return false
func (mG MyGeneric[T]) canHandle(value any) bool {
// how to get what T is the same type as value
}
对于正常值,只需实例化T
直接获取其值并reflect.TypeOf()
它。但我们可以声明一个[0]T
并取其元素类型,因为:
-
[0]T
takes 0 memory while T
may be as large as T
, which would waste a lot of stack and heap 1 if T
is something like [4096]int
.
- A raw
T
不适用于接口类型。reflect.TypeOf()
在 nil 接口值(无论是否为空接口)上将返回reflect.Type(nil)
,后续使用会引起恐慌。
package main
import (
"fmt"
"reflect"
)
type MyGeneric[T any] struct {
}
func (mG MyGeneric[T]) canHandle(value any) bool {
var zero [0]T
tt := reflect.TypeOf(zero).Elem()
vt := reflect.TypeOf(value)
fmt.Printf("-> %v covers %v\n", tt, vt)
return vt.AssignableTo(tt)
}
type empty struct{}
func main() {
fmt.Printf("%v\n", MyGeneric[string]{}.canHandle(""))
fmt.Printf("%v\n", MyGeneric[any]{}.canHandle(""))
fmt.Printf("%v\n", MyGeneric[string]{}.canHandle(1))
fmt.Printf("%v\n", MyGeneric[MyGeneric[struct{}]]{}.canHandle(MyGeneric[struct{}]{}))
fmt.Printf("%v\n", MyGeneric[MyGeneric[struct{}]]{}.canHandle(MyGeneric[empty]{}))
}
Output:
-> string covers string
true
-> interface {} covers string
true
-> string covers int
false
-> main.MyGeneric[struct {}] covers main.MyGeneric[struct {}]
true
-> main.MyGeneric[struct {}] covers main.MyGeneric[main.empty]
false
1 Not sure if it can be optimized out or whether it allocates on heap or stack or both, because it is passed into reflect.TypeOf
after upcasting to an interface{}
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)