想象一下我有以下結構:
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
}
uj5u.com熱心網友回復:
只需直接實體化T即可獲取其值。
type MyGeneric[T any] struct {
}
func (mG MyGeneric[T]) canHandle(value any) bool {
var t T
tt := reflect.TypeOf(t)
vt := reflect.TypeOf(value)
fmt.Printf("-> %v == %v\n", tt, vt)
return tt == vt
}
type empty struct{}
func main() {
fmt.Printf("%v\n", MyGeneric[string]{}.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]{}))
}
輸出:
-> string == string
true
-> string == int
false
-> main.MyGeneric[struct {}] == main.MyGeneric[struct {}]
true
-> main.MyGeneric[struct {}] == main.MyGeneric[main.empty]
false
如果您擔心T分配太多未使用的堆疊,請將其改為陣列:
var tArr [0]T
tt := reflect.TypeOf(tArr).Elem()
uj5u.com熱心網友回復:
它尚未實施。有一個關于將必要的方法添加到reflect.Type.
從 Go 1.19 開始,當前的解決方法是決議從TypeOf. 像這樣的東西:
var r = regexp.MustCompile("[A-Za-z0-9_] \\.[A-Za-z0-9_] \\[(.*)\\]")
func (mG MyGeneric[T]) canHandle(value any) {
tname := reflect.TypeOf(mG).String() // this is `main.MyGeneric[string]`
match := r.FindStringSubmatch(tname)
fmt.Println(match[1]) // string
}
如果目標只是獲取型別引數的名稱,則此方法。如果您需要對其進行進一步計算,例如將其與canHandle函式中的其他型別進行比較,@SOFe 的答案提供了一個更好的解決方案,它不依賴于泛型型別的任意字串表示。
uj5u.com熱心網友回復:
另一種解決方案是在結構中添加一個 placeHolder 欄位,該欄位可用于通過型別開關獲取其型別以避免反射:
type MyGeneric[T string | int] struct {
placeHolder T
}
func (mG MyGeneric[T]) canHandle(value any) bool {
switch t1 := any(p.placeHolder).(type) {
case any:
switch t2 := value.(type) {
case any:
return t1 == t2
}
}
return false
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/511349.html
標籤:去仿制药反射
上一篇:使用洗掉和泛型轉換型別的簡潔方法
下一篇:如何通過泛型更改結構標簽
