我是Go的新手,我遇到了这个问题。我需要创建一种“调度程序”,它将接收一个字符串并返回一个基于字符串实例化的类型。例如:
AnimalType := mymap["animal"]
newAnimal := new(AnimalType)
有办法吗?
提前致谢。
答案 0 :(得分:2)
您可以使用reflect
包执行此操作,但应注意最终您必须知道具体类型才能真正做到这一点。
编辑:让我们知道。这首先是一个非常糟糕的想法,如果你这样做,你应该重新思考一下。 Go是一种静态类型语言,除非您真的需要使用反射包,否则应尽可能远离它。即便如此,在大多数情况下,这已经为您完成了。以JSON Marshal / Unmarshaller为例。在它的核心,他们做了一些讨厌的反思,但它已经为你照顾,只需使用它。
重要的是要注意,如果类型断言(.(*Thing1)
行)不是正确的类型,它将panic
行。见https://tour.golang.org/methods/15
在操场上测试:https://play.golang.org/p/DhiTnCVJi1
package main
import (
"fmt"
"reflect"
)
type Thing1 bool
type Thing2 int
type Thing3 struct {
Item string
}
func main() {
m := map[string]reflect.Type{}
var t1 Thing1
var t2 Thing2
var t3 Thing3
m["thing1"] = reflect.TypeOf(t1)
m["thing2"] = reflect.TypeOf(t2)
m["thing3"] = reflect.TypeOf(t3)
// later on
// thing1
newT1Value := reflect.New(m["thing1"])
// you use * here because a pointer to a boolean type isn't useful
newT1 := *newT1Value.Interface().(*Thing1) // cast to concrete type
fmt.Printf("T1: %v\n", newT1)
// thing2
newT2Value := reflect.New(m["thing2"])
// you use * here because a pointer to an int type isn't useful
newT2 := *newT2Value.Interface().(*Thing2)
fmt.Printf("T2: %v\n", newT2)
// thing3
newT3Value := reflect.New(m["thing3"])
// you can choose to use * or not here. Pointers to structs are actually useful
newT3 := newT3Value.Interface().(*Thing3)
newT3.Item = "Hello world"
fmt.Printf("T3: %#v\n", newT3)
}