dongshetao1814
dongshetao1814
2016-04-11 16:20
浏览 43
已采纳

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

I'm trying to do this:

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

But I can't because when I try to build, I get this error:

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

Here is the relevant source code of the library I'm trying to use:

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
}

As you can see, all of the other Events have the field Type. How can I access this?

Solution

This how I ended up polling events in this SDL2 binding for Go, in case anyone is wondering:

func PollEvents() {
    for {
        if event := sdl.PollEvent(); event != nil {
            switch event.(type) {
            case *sdl.QuitEvent:
                utils.Running = false
            }
        } else {
            break
        }
    }
}

图片转代码服务由CSDN问答提供 功能建议

我正在尝试执行此操作:

  if事件 .Type == sdl.QUIT {
 utils.Running = false 
} 
   
 
 

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

  ./mm.go:11:event.Type未定义(类型sdl.Event没有字段或方法类型)
    
 
 

这是我要使用的库的相关源代码:

  type Event interface {} 
 
type CEvent struct {\  n输入uint32 
 _ [52] byte // padding 
} 
 
type CommonEvent struct {
输入uint32 
时间戳记uint32 
} 
 
 // WindowEvent(https://wiki.libsdl。  org / SDL_WindowEvent)
type WindowEvent结构{
类型uint32 
时间戳uint32 
 WindowID uint32 
事件uint8 
 _ uint8 //填充
 _ uint8 //填充
 _ uint8 //填充
 Data1 int32  
 Data2 int32 
} 
   
 
 

如您所见,所有其他事件都有该字段 <代码>类型。 我如何访问它?

解决方案

这就是我最终在用于Go的此SDL2绑定,以防有人怀疑:

  func PollEvents(){
 对于{
 if event:= sdl.PollEvent();  event!= nil {
切换事件。(类型){
 case * sdl.QuitEvent:
 utils.Running = false 
} 
}否则{
 break 
} 
} 
} \  n   
 

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • douyue8685
    douyue8685 2016-04-11 16:29
    已采纳

    You actually can't. Interfaces only define a method set that is available on a type, they do nothing to expose fields. In your case I would recommend doing a type switch. It would look a little like this;

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

    You may want to structure your code a bit differently depending on what you're doing with the instance after this but that gives you the basic idea. You can also do a type assertion with a single type like; v, err := myInstance.(CommonEvent) but I doubt it would be as effective here. It also returns an error if the type of myInstance is not CommonEvent so it's not really the best way to go about figuring out what type and interface instance may be.

    点赞 评论
  • dream_life5200
    dream_life5200 2016-04-11 16:23

    You will need to know the type. Let's say we know it's a CEvent:

    cEvent, ok := Event.(CEvent)
    if !ok {
        // You lied, not a CEvent
        return
    }
    
    // Otherwise, you can get the type!
    fmt.Println(cEvent.Type)
    

    Of course if you don't know the type, you can keep type asserting until you get it right. Otherwise, throw an error, return a default value, etc:

    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>
    }
    
    点赞 评论
  • douxiong2001
    douxiong2001 2016-04-11 16:41

    You can spend a lot of time doing reflection calls or trying to guess the type or using type switches.

    Or you can just define an interface with functions that return the information you need.

    For example you could do

    type Event interface {
        GetCommonEvent() *CommonEvent
        GetWindowEvent() *WindowEvent
    }
    
    点赞 评论

相关推荐