如何在Go中访问界面的字段?

时间:2016-04-11 16:20:54

标签: go struct interface

我试图这样做:

getList() {
  this._http.get('../fake-data/someFile.json')
    .map(response => response.json())
    .subscribe(
      data => {
        this.dataStore.meetingList = data;
        this.meetingListObserver.next(this.dataStore.meetingList);
      },
      err => console.log('>>>', 'Could not load meetings list. Error: ', err),
      () => console.log('>>>', 'Done with getting meetings list.')
    );
}

但是我不能,因为当我尝试构建时,我收到了这个错误:

if event.Type == sdl.QUIT {
    utils.Running = false
}

以下是我尝试使用的库的相关源代码:

 ./mm.go:11: event.Type undefined (type sdl.Event has no field or method Type)

如您所见,所有其他事件都有字段type Event interface{} type CEvent struct { Type uint32 _ [52]byte // padding } type CommonEvent struct { Type uint32 Timestamp uint32 } // WindowEvent (https://wiki.libsdl.org/SDL_WindowEvent) type WindowEvent struct { Type uint32 Timestamp uint32 WindowID uint32 Event uint8 _ uint8 // padding _ uint8 // padding _ uint8 // padding Data1 int32 Data2 int32 } 。我该如何访问?

解决方案

这是我如何在this SDL2 binding for Go中轮询事件,以防有人想知道:

Type

3 个答案:

答案 0 :(得分:3)

你实际上不能。接口只定义一个类型上可用的方法集,它们不会公开字段。在你的情况下,我建议做一个类型切换。它看起来有点像这样;

     switch v := myInstance.(type) {
                case CEvent:
                        fmt.Println(v)
                case CommonEvent:
                        fmt.Println(v)
                case WindowEvent:
                        fmt.Println(v)
                default:
                        fmt.Println("unknown")
        }

您可能希望根据您在此之后对实例所做的事情来稍微改变您的代码,但这会为您提供基本的想法。您也可以使用单一类型执行类型断言; v, err := myInstance.(CommonEvent)但我怀疑它在这里会有效。如果myInstance的类型不是CommonEvent,它也会返回错误,因此这不是确定类型和接口实例可能的最佳方式。

答案 1 :(得分:0)

您需要知道类型。让我们说我们知道它是一个CEvent:

cEvent, ok := Event.(CEvent)
if !ok {
    // You lied, not a CEvent
    return
}

// Otherwise, you can get the type!
fmt.Println(cEvent.Type)

当然,如果您不知道知道类型,您可以保持类型断言,直到您做对了。否则,抛出错误,返回默认值等:

func getType(i interface{}) uint32 {
    cEvent, ok := i.(CEvent)
    if ok {
        return cEvent.Type
    }

    commonEvent, ok := i.(CommonEvent)
    if ok {
        return commonEvent.Type
    }

    // Etc

    return <default>
}

答案 2 :(得分:0)

您可以花很多时间进行反射调用或尝试猜测类型或使用类型开关。

或者您可以定义一个界面,其中包含返回所需信息的函数。

例如你可以做

type Event interface {
    GetCommonEvent() *CommonEvent
    GetWindowEvent() *WindowEvent
}