当前位置: 首页 > 面试题库 >

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

戈巴英
2023-03-14
问题内容

我现在遇到的情况与在该线程中询问的情况相同:
具有嵌入式匿名接口的结构的含义?

  type A interface {
     Foo() string
  }

  type B struct {
     A
     bar string
  }

习惯上,来自OOP语言的背景,这种模式对我来说似乎是“试图说”,因为B必须实现接口A。但是现在我知道“
Go是不同的”。因此,无论有没有进行编译,它都比我最初期望的编译时检查要好。

  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的开销很大,而且因为该函数通常(如果 确实 存在)可能会产生副作用我现在不想要…

我是否需要类似编译器类型检查的运行时实现之类的东西?还是有更简单的方法?我在想这个吗?

上面的示例在Go游乐场


问题答案:

你不需要在我心中反思

method_in_table := B.Foo
fmt.Printf("%T \n", method_in_table)

将输出你

func(main.B) string

接口类型A在预先声明的nil初始化,没有动态类型

var a A
if a==nil{
    fmt.Printf("It's nil")
}
a.Foo()

会给你同样的错误。所以实际检查可以

if b.A != nil { b.Foo()}


 类似资料:
  • 问题内容: 我必须为具有相似签名和返回值(一个对象和一个错误)的多个函数编写单元测试,这些函数必须通过相似的测试条件。 我想避免写: (见本去操场例子更完整的上下文) (是的,去游乐场还不支持,只有和问题6511是有没有要求该功能) 为了只编写一个测试,您将 如何使用反射(包): 依次调用每个函数? 测试他们的返回值? 但是我想念一个完整的示例来调用函数并在测试中使用返回的值。 问题答案: 一旦我

  • 问题内容: 我一直在尝试找出能做什么或可能有什么好处,但同时我想知道是否可以通过反射投射对象。 首先,我认为以下几行可能会错误地起作用: 但是,如果没有显式强制转换,它将无法正常工作。 那么什么是上课方法呢?并且仅通过反射来投射对象是否有可能,因此您找到了该对象的类,对其进行使用并以某种方式对其进行了投射? 问题答案: 一个有效的示例: 这使您可以编写: 您的代码不起作用的原因是Class.for

  • 如果反射值对象(reflect.Value)中值的类型为函数时,可以通过 reflect.Value 调用该函数。使用反射调用函数时,需要将参数使用反射值对象的切片 []reflect.Value 构造后传入 Call() 方法中,调用完成时,函数的返回值通过 []reflect.Value 返回。 下面的代码声明一个加法函数,传入两个整型值,返回两个整型值的和。将函数保存到反射值对象(refle

  • 问题内容: 我有一个/ / / etc ..值存储在中,并且想要确定它是否未初始化,这意味着它的值是 要么 我该如何检查? 问题答案: 据我了解,您想要的是: 在谈论接口和时,人们总是对两个截然不同且无关的事物感到困惑: 甲接口值,其是不具有一个接口值 的基础值 。这是接口类型的零值。 非接口值(即,它具有 基础值 ),但是其基础值是其基础类型的零值。例如,基础值是映射,指针或0数字等。 据我了解

  • 我在React中有一个表,它的行没有html元素,所以我可以用通常的方式进行映射。它的数据通过道具。下面是一个例子: 我想做一些像

  • 我尝试使用java Spring映射对象DTO到对象正常 我尝试调用接口映射器,因为服务,但我有NullPointerExctive,似乎接口没有注入服务,我使用自动配置,我退出了这个 服务 制图员 错误 我尝试调试,我看到iUserMapper是空的,我不知道如何调用,因为服务 谢谢!