ANi*_*sus 2 json types interface dynamic go
简单版本
如何根据字符串的值创建某种类型的变量?
type ta struct { a int }
type tb struct { b float }
type tc struct { c string }
t := "tb"
v := MagicVarFunc(t) // Returns a new allocated var of type interface{}
v.(tb).b = 8.3
Run Code Online (Sandbox Code Playgroud)
真实的例子
在我的,令人惊讶的是,下面的工作示例中,我基于字符串动态创建变量.这是通过在映射中注册每个结构类型来完成的,其中字符串是键,而类型的nil指针是值.
每种类型都使用New()方法实现一个接口,该方法返回该特定类型的新变量.
下面的示例非常接近我想要做的事情,其中每个操作都有一组JSON编码数据,这些数据将填充相应的结构.我构建它的方式也是因为我希望能够创建我注册到地图的新独立动作.
我不确定现在是否滥用这门语言.
如果我完全不在意,愿任何人给我任何指示吗?有一个明显更容易的方法吗?
package main
import (
"fmt"
"encoding/json"
)
// All I require of an action is that it may be executed
type ActionHandler interface {
Exec()
New() ActionHandler
}
// My list of actions
var mActions = make(map[string]ActionHandler)
// Action Exit (leaving the program)
type aExit struct {}
func (s *aExit) Exec() { fmt.Println("Good bye") }
func (s *aExit) New() ActionHandler { return new(aExit) }
func init() {
var a *aExit
mActions[`exit`] = a
}
// Action Say (say a message to someone)
type aSay struct {
To string
Msg string
}
func (s *aSay) Exec() { fmt.Println(`You say, "` + s.Msg + `" to ` + s.To) }
func (s *aSay) New() ActionHandler { return new(aSay) }
func init() {
var a *aSay
mActions[`say`] = a
}
func inHandler(action string, data []byte) {
a := mActions[action].New()
json.Unmarshal(data, &a)
a.Exec()
}
func main(){
inHandler(`say`, []byte(`{"to":"Sonia","msg":"Please help me!"}`))
inHandler(`exit`, []byte(`{}`))
}
Run Code Online (Sandbox Code Playgroud)
new如果可以Type在运行时获取值,则可以使用反射来获取零值,或者使用反射分配类型的新值(如).但是,我认为没有办法Type从字符串中获取.您需要具有该类型的值才能获得该类型.
我采纳了你的想法,使用地图.我将字符串映射到您可以使用的类型本身,它reflect.TypeOf从接口值中获取类型.然后我习惯reflect.Zero得到该类型的零值(对于每种类型都存在一个方便的值).然后我把价值作为一个界面.
package main
import "reflect"
type ta struct { a int }
type tb struct { b float64 }
type tc struct { c string }
var mActions map[string]reflect.Type = make(map[string]reflect.Type)
func init() {
var a ta
mActions[`ta`] = reflect.TypeOf(a)
var b tb
mActions[`tb`] = reflect.TypeOf(b)
var c ta
mActions[`tc`] = reflect.TypeOf(c)
}
func MagicVarFunc(action string) interface{} {
return reflect.Zero(mActions[action]).Interface()
}
func main() {
t := "tb"
v := MagicVarFunc(t) // Returns a new allocated var of type interface{}
x := v.(tb)
x.b = 8.3
}
Run Code Online (Sandbox Code Playgroud)