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

用空接口返回类型的参数接受函数

皇甫德庸
2023-03-14
问题内容

我想了解为什么下面的代码片段无法编译。将函数接受为可能具有任何返回类型的函数参数的Go方法是什么?

package main

func main() {
    test(a) // Error: cannot use a (type func() string) as type func() interface {} in argument to test
    test(b) // Error: cannot use b (type func() int) as type func() interface {} in argument to test
}

func a() string {
    return "hello"
}

func b() int {
    return 1
}

func test(x func() interface{}) {

    // some code...
    v := x()
    // some more code....
}

播放:https://play.golang.org/p/CqbuEZGy12

我的解决方案基于Volker的答案:

package main

import (
    "fmt"
)

func main() {

    // Wrap function a and b with an anonymous function
    // that has an empty interface return type. With this
    // anonymous function, the call signature of test
    // can be satisfied without needing to modify the return
    // type of function a and b.

    test(func() interface{} {
        return a()
    })

    test(func() interface{} {
        return b()
    })
}

func a() string {
     return "hello"
}

func b() int {
    return 1
}

func test(x func() interface{}) {
    v := x()
    fmt.Println(v)  
}

播放:https://play.golang.org/p/waOGBZZwN7


问题答案:

你绊倒了围棋新人一个非常普遍的误解:空接口interface{}不能 意味着“任何类型”。确实不是。Go是静态类型的。空接口interface {}是实际的(强类型),例如stringstruct{Foo int}interface{Explode() bool}

这意味着如果某物具有该类型,interface{}则它具有该类型而不是“任何类型”。

您的职能

func test(x func() interface{})

接受一个参数。此参数是一个(无参数函数),它返回特定类型type
interface{}。您可以将test与此签名匹配的任何函数传递给它:“无参数并返回interface{}”。没有您的功能a并且b匹配此签名。

如上所述:interface {}“ whatever”不是“ whatever”的神奇缩写,它是一种独特的静态类型。

您必须将例如a更改为:

func a() interface{} {
    return "hello"
}

现在,当您返回string不是type的a时,这可能看起来很奇怪interface{}。之所以可行,是因为任何类型都可以分配给该类型的变量interface{}(因为每种类型至少都没有方法:-)。



 类似资料:
  • 我试图通过RESTendpoint将数据从一个服务器发送到另一个服务器: 服务器B启动此请求: 服务器A接收请求并返回文件: 因此,很明显,我必须将声明更改为: 或者到 然后错误消失了,但我丢失了HttpStatus。回复时是否有确认信息?这里的正确解决方案是什么?

  • 问题内容: 我的包中有一个结构,上面有耗时的方法,通过工厂函数进行构造也很耗时。因此,在依赖于该其他结构的包中,我希望能够在创建后使用伪造的工厂函数和伪造的结构对其进行测试。由于结构是通过工厂函数构造的,因此我想伪造工厂函数,并在测试期间将替代工厂函数传递给我的结构。 昂贵的包装的一个例子是: 我的主包装使用以下代码: 但是,此代码抱怨以下错误: 。\ main.go:6:不能在字段值中使用昂贵的

  • 我希望为我的2D游戏创造平滑的道路。看着这正是我需要的东西。每一篇文章,甚至在上,都给它一个类型,并用构造函数传递所有控制点和一个。这似乎是过时的,不再接受任何类型参数,没有它,它只能与路径工作。构造函数也不接受控制点列表。 这会产生以下错误:

  • 流接口中的映射函数定义如下: 函数参数列表与函数接口自己的规范一致 方法是 这意味着它需要一个T,但返回一个R。但我正在运行这个代码 奇怪的是,为什么它能工作,但论点类型似乎不匹配?没有简单的方法来解释它,但我的理解是,一个函数应该接受类型T的输入并返回类型R。当它在流中使用时,它接受类型String的输入并返回类型int(即String.length())。但是小溪。map被键入以返回与流相同的

  • 但是,我的问题在于如何理解当我尝试使用而不是执行相同操作时会发生什么 这里的例子是,有一个接口定义被定义为接受一个接口参数,实际上,这个接口参数是由实现接口的枚举实现的: 我有两个接口: 我看到了一些关于,但这扩展了我的理解。请救命! 顺便说一句,我认为返回类之前的泛型声明被用来指定“T”以用于类型侵蚀的目的,这是正确的吗?

  • 我有一个接口,它的函数当前返回它自己。但是,我希望任何实现类都返回该类,而不是基接口。例如,在这个简化的示例中,它工作得很好: 这显然是失败的,因为重写函数不再与接口中的声明匹配。 我需要baz()返回Class而不是Interface,因为调用者可以以任意顺序调用bar和baz任意次数,但是目前所有bar()调用必须在所有baz()调用之前,除非我们重复地向下调用。 更复杂的是foo()函数,它