golang转换接口到struct

时间:2018-03-23 11:06:43

标签: go

type SipField interface {
    Info() (id, name, defaultValue string, length int)
}

type Field string

func (f *Field) Get() string {
    return string(*f)
}

func (f *Field) Set(s string) {
    *f = Field(s)
}

type CommandID Field

func (cid *CommandID) Info() (id, name, defaultValue string, length int) {
    return "", "command ID", "", 2
}

type Language Field

func (l *Language) Info() (id, name, defaultValue string, length int) 
{
    return "", "language", "019", 3
}

func InitField(f interface{}, val string) error {
    sipField, ok := f.(SipField)
    if !ok {
        return errors.New("InitField: require a SipField")
    }
    _, _, defaultValue, length := sipField.Info()
    field, ok := f.(*Field)
    if !ok {
     return errors.New("InitField: require a *Field")
    }
    return nil
}

如何在interface{}函数中将Field(CommandID, Language...)转换为InitField()?我尝试直接键入断言

field, ok := f.(*Field)

但它无法正常工作。我曾尝试使用unsafe.Pointer但也失败了。

1 个答案:

答案 0 :(得分:6)

查看Go参考中的Type assertions章节。它声明:

  

x.(T)

     

更确切地说,如果T不是接口类型,则x。(T)断言x的动态类型与类型T相同。

类型CommandID和字段与Type identity中描述的不同。

  

定义的类型总是与任何其他类型不同。

两种类型CommandId和Fields都定义为Type definitions中的描述。

  

类型定义创建一个新的,不同的类型,它具有与给定类型相同的基础类型和操作,并将标识符绑定到它。

     

TypeDef = identifier Type .

你只能做

field, ok := f.(*CommandID)

field, ok := f.(*Language)

正如@mkopriva在评论中提到的,您可以稍后将代码转换为*Field,但这似乎不是您的目标。

其他解决方案是使用Set和Get方法引入Field接口。然后,您需要为每种实现类型提供实现。