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但也失败了。
答案 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接口。然后,您需要为每种实现类型提供实现。