猿问

如何在 Go 中访问接口的字段?

我正在尝试这样做:


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

}

如您所见,所有其他事件都有字段Type。我怎样才能访问这个?


解决方案

这就是我最终在Go 的 SDL2 绑定中轮询事件的方式,以防有人想知道:


func PollEvents() {

    for {

        if event := sdl.PollEvent(); event != nil {

            switch event.(type) {

            case *sdl.QuitEvent:

                utils.Running = false

            }

        } else {

            break

        }

    }

}


慕尼黑5688855
浏览 190回答 3
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,它也会返回错误,因此这并不是确定可能是什么类型和接口实例的最佳方法。

跃然一笑

您将需要知道类型。假设我们知道这是一个 CEvent:cEvent, ok := Event.(CEvent)if !ok {&nbsp; &nbsp; // You lied, not a CEvent&nbsp; &nbsp; return}// Otherwise, you can get the type!fmt.Println(cEvent.Type)当然,如果你不知道类型,你可以保持类型断言,直到你正确为止。否则,抛出错误,返回默认值等:func getType(i interface{}) uint32 {&nbsp; &nbsp; cEvent, ok := i.(CEvent)&nbsp; &nbsp; if ok {&nbsp; &nbsp; &nbsp; &nbsp; return cEvent.Type&nbsp; &nbsp; }&nbsp; &nbsp; commonEvent, ok := i.(CommonEvent)&nbsp; &nbsp; if ok {&nbsp; &nbsp; &nbsp; &nbsp; return commonEvent.Type&nbsp; &nbsp; }&nbsp; &nbsp; // Etc&nbsp; &nbsp; return <default>}

慕莱坞森

您可能会花费大量时间进行反射调用或尝试猜测类型或使用类型切换。或者,您可以定义一个接口,其中包含返回所需信息的函数。例如你可以做type Event interface {&nbsp; &nbsp; GetCommonEvent() *CommonEvent&nbsp; &nbsp; GetWindowEvent() *WindowEvent}
随时随地看视频慕课网APP

相关分类

Go
我要回答