使用嵌入在struct中的接口进行反射-如何检测“真实”函数?

问题描述 投票:6回答:5

我现在遇到的情况与该线程询问的情况相同:Meaning of a struct with embedded anonymous interface?

  type A interface {
     Foo() string
  }

  type B struct {
     A
     bar string
  }

习惯上来说,来自OOP语言的背景,这种模式对我来说似乎是“试图说”,因为B必须实现接口A。但是现在我知道“ Go是不同的”。因此,无论是否有a

都可以进行编译,而不是我最初期望的编译时检查
  func (B) Foo() string { .... }

现在。正如上面的问题指出的那样(解释):“当您只想实现接口的/ part /时,在结构中使用嵌入式接口非常有用”。

[大概是因为这种嵌入所发生的情况与其他所有情况一样-类型B的值将具有类型A的匿名接口值作为字段。就我个人而言,尽管我发现正交性得到了改善,但同时也使反射包让我以这种方式直接从B的类型中获取A的方法感到困惑,而如果没有使用接收方B的方法,则不会出错/为零。但是-这个问题与背后的想法无关-与b := B{}之后如何初始化接口值有关:

 func main() {
    bType := reflect.TypeOf(B{})
    bMeth, has := bType.MethodByName("Foo")
    if has {
      fmt.Printf("HAS IT: %s\n",bMeth.Type.Kind())
      res := bMeth.Func.Call([]reflect.Value{reflect.ValueOf(B{})})
      val := res[0].Interface()
      fmt.Println(val)
  } else {
      fmt.Println("DOESNT HAS IT")
  }
}

运行此命令会导致严重的恐慌

 HAS IT: func
 panic: runtime error: invalid memory address or nil pointer dereference

... 或没有-取决于编译器/运行时是否能够找到上述方法。因此:如何在触发之前检测到该情况?

即-关于bMeth值,我可以用来查看反射返回的Method和func值中没有“真实”实现吗?更确切地说,是“指向匿名接口值的函数表中的函数的指针为零”,还是从没有实现的反射反射接口中提取的方法到底发生了什么?

将整个程序包装在goroutine中并尝试在defer / panic下运行该函数不是答案-不仅是因为panic / defer的开销很大,而且因为如果< >存在,现在有我不想要的副作用...我是否希望像运行时实现这样的东西能够反映出编译器的类型检查?还是有更简单的方法?我是不是在想这个错误?

Above example in a Go playground

我现在遇到的情况与在该线程中被问到的情况相同:具有嵌入式匿名接口的结构的含义?类型A接口{Foo()字符串}类型B结构{A ...

reflection interface go embedding
5个回答
3
投票
你不需要在我心中反思

2
投票
在您已经收到很好的答案之后,让我投入两美分。

1
投票
我认为这是不可能的。从reflect的文档和code中可以看到,无法知道是在类型上还是在promoted上定义了方法。似乎恐慌恢复是您可以在此处执行的最佳操作。

1
投票
这里有3个问题。

0
投票
这个问题很老,有一些好的答案,但是没有一个问题可以解决。
© www.soinside.com 2019 - 2024. All rights reserved.