为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕尼黑5688855 2022-01-04 10:49:40
我正在尝试这样做: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        }    }}
查看完整描述

3 回答

?
心有法竹

TA贡献1866条经验 获得超5个赞

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


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


查看完整回答
反对 回复 2022-01-04
?
跃然一笑

TA贡献1826条经验 获得超6个赞

您将需要知道类型。假设我们知道这是一个 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>

}


查看完整回答
反对 回复 2022-01-04
?
慕莱坞森

TA贡献1810条经验 获得超4个赞

您可能会花费大量时间进行反射调用或尝试猜测类型或使用类型切换。


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


例如你可以做


type Event interface {

    GetCommonEvent() *CommonEvent

    GetWindowEvent() *WindowEvent

}


查看完整回答
反对 回复 2022-01-04
  • 3 回答
  • 0 关注
  • 189 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信