foo.Name未定义(类型interface {}没有Name字段或方法)

huangapple go评论95阅读模式
英文:

foo.Name undefined (type interface {} has no field or method Name)

问题

我使用原生的golang包"container/list"来管理一个堆栈中的inotify事件。当我访问堆栈的项时,出现了一个类型错误(我认为是这个原因)。

import (
    "golang.org/x/exp/inotify"
    "container/list"
    "log"
    "fmt"
)

func main() {
    stack := list.New()
    watcher, err := inotify.NewWatcher()

    if err != nil {
        log.Fatal(err)
    }

    err = watcher.Watch(os.Args[1])
    if err != nil {
        log.Fatal(err)
    }

    for {
        select {
        case ev := <-watcher.Event:
            stack.PushFront(ev)

            fmt.Printf("%#v\n", ev)
        }

        foo := stack.Front().Value

        fmt.Printf("%#v\n", foo)
        log.Println("Name: ", foo.Name)
    }
}

当我输出__ev__变量时,对象的类型是__&inotify.Event__。
当我弹出一个项并输出变量时,我的对象类型是__&inotify.Event__。

根据错误信息,我认为这是一个接口接受的类型对象的问题,但我找不到如何定义类型的方法。

英文:

I use the native golang package "container/list" to manage inotify event in a stack. When I access at stack's item, I have a fail with the type (I think).

import (
	&quot;golang.org/x/exp/inotify&quot; 
    &quot;container/list&quot;
    &quot;log&quot;
    &quot;fmt&quot;
)

func main() {
    stack := list.New()
    watcher, err := inotify.NewWatcher()

    if err != nil {
        log.Fatal(err)
    }

   err = watcher.Watch(os.Args[1])
   if err != nil {
       log.Fatal(err)
   }

   for {
       select {
	       case ev := &lt;-watcher.Event:
			   stack.PushFront(ev)
   
               fmt.Printf(&quot;%#v\n&quot;, ev)
        }

        foo := stack.Front().Value
   
        fmt.Printf(&quot;%#v\n&quot;, foo)
        log.Println(&quot;Name: &quot;, foo.Name)
    }
}

When I dump ev variable, the object type is &inotify.Event.
When I pop one item and I dump the variable, my object type is &inotify.Event.

With the error message I think it's a problem with type object accept by interface but I don't find how define type.

答案1

得分: 9

你需要对foo进行类型断言,将其断言为*inotify.Event类型,堆栈不知道它是什么,它只保存interface{}对象。

你需要做的是像这样:

elem := stack.Front().Value
if foo, ok := elem.(*inotify.Event); ok {
       fmt.Printf("%#v\n", foo)
       log.Println("Name: ", foo.Name)
}

ok部分确保如果它不是一个事件,你的程序不会崩溃。当然,你需要处理它不是事件的情况。

有关接口转换和类型断言的更多信息,请参阅:https://golang.org/doc/effective_go.html#interface_conversions

英文:

You need to do type-assertion for foo into *inotify.Event, the stack doesn't know what it is, it just holds interface{} objects.

What you need to do is something like:

elem := stack.Front().Value
if foo, ok := elem.(*inotify.Event); ok {
       fmt.Printf(&quot;%#v\n&quot;, foo)
       log.Println(&quot;Name: &quot;, foo.Name)
}

The ok bit makes sure if it's not an event, your program won't crash. Of course you need to handle the case that it isn't.

More info on interface conversions and type assertions: https://golang.org/doc/effective_go.html#interface_conversions

huangapple
  • 本文由 发表于 2015年6月24日 20:45:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/31026980.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定