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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With