Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert interface to struct

Tags:

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 } 

How should I do for converting interface{} to Field(CommandID, Language...) in InitField() function? I try to directly type assert by

field, ok := f.(*Field) 

but it not working.I have tried to use unsafe.Pointer but failed also.

like image 571
wangjun Avatar asked Mar 23 '18 11:03

wangjun


1 Answers

Have a look at Type assertions chapter in Go reference. It states:

x.(T)

More precisely, if T is not an interface type, x.(T) asserts that the dynamic type of x is identical to the type T.

Types CommandID and Field are not identical as described in Type identity.

A defined type is always different from any other type.

Both types CommandId and Fields are defined as descirbed in Type definitions.

A type definition creates a new, distinct type with the same underlying type and operations as the given type, and binds an identifier to it.

TypeDef = identifier Type .

You can only do

field, ok := f.(*CommandID) 

or

field, ok := f.(*Language) 

As @mkopriva mentioned in the comment, you can do type conversion later to *Field but this it does not seem to be your goal.

Other solution is to introduce a Field interface with Set and Get methods. Then you will need to provide an implementation for every implementing type.

like image 169
Grzegorz Żur Avatar answered Oct 02 '22 11:10

Grzegorz Żur