'Convert interface to struct

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.

go


Solution 1:[1]

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 described 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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community