dqzve68846 2017-03-30 17:18
浏览 13

是否可以在地图中存储Type,然后在以后使用它在Go lang中实例化对象? [重复]

This question already has an answer here:

I am new to Go and I have this problem. I need to make a kind of "dispatcher" that will receive a string and return a type to be instantiated based on the string. For example:

AnimalType := mymap["animal"]
newAnimal := new(AnimalType)

Is there a way to do so?

Thanks in advance.

</div>
  • 写回答

1条回答 默认 最新

  • dsghpgmay31938863 2017-03-30 17:34
    关注

    You can do this with the reflect package, though it should be noted that eventually you have to know the concrete type to really do much with it.

    EDIT: LET IT BE KNOWN. This is a very BAD idea in the first place, and if you are doing this, you should probably rethink things. Go is a statically typed language, and unless you REALLY need to use the reflect package, you should stay away from it if possible. Even then, in most cases, this has already been done for you. Take, for instance, the JSON Marshal/Unmarshaller. At its core, they do some nasty reflection stuff, but it is already taken care of for you, just use it.

    It is important to note that the type assertions (the .(*Thing1) lines) will panic if it isn't the right type. See https://tour.golang.org/methods/15

    Test on playground: 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
    ", 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
    ", 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
    ", newT3)
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 Centos7 / PETGEM
  • ¥15 csmar数据进行spss描述性统计分析
  • ¥15 各位请问平行检验趋势图这样要怎么调整?说标准差差异太大了
  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题
  • ¥15 wpf界面一直接收PLC给过来的信号,导致UI界面操作起来会卡顿
  • ¥15 init i2c:2 freq:100000[MAIXPY]: find ov2640[MAIXPY]: find ov sensor是main文件哪里有问题吗
  • ¥15 运动想象脑电信号数据集.vhdr
  • ¥15 三因素重复测量数据R语句编写,不存在交互作用
  • ¥15 微信会员卡等级和折扣规则
  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗