可以定义一个返回接口的无名函数吗?

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

Is it possible to define a nameless function that returns an interface?

问题

我正在尝试理解一些在线的Go代码。

var botInterface func(*Server) eintefaces.BotInterface

func SetBotInterface(b func(*Server) einterface.BotInterface){
   botInterface = b 
}

有人知道这段代码在说什么吗?这里没有实现匿名函数。从我所了解的来看,botInterface 被定义为一个返回接口的函数。目前 botInterface 是 nil,这是唯一相关的代码。

英文:

I am trying to understand some Go code online.

var botInterface func(*Server) eintefaces.BotInterface

func SetBotInterface(b func(*Server) einterface.BotInterface){
   botInterface = b 
}

Does anyone know what the code is saying? There is no implementation of the nameless function. From what I can tell is that botInterface is defined as a function that returns a interface. Currently botInterface is nil and that is the only related code.

答案1

得分: 6

func(*Server) eintefaces.BotInterface 不是一个匿名函数,而是一个函数类型。它是一个以 *Server 作为参数并返回类型为 eintefaces.BotInterface 的函数类型。

botInterface 是一个未导出的变量。它的类型是上述描述的函数类型。

SetBotInterface() 是一个导出的函数,它可以设置(赋值)给未导出的 botInterface 变量。你需要传递一个相同类型的函数值,并将其简单地赋值给未导出的变量(否则无法访问未导出的变量)。

以下是一个类似的示例用法:

var f func(string) io.Writer

func SetF(v func(string) io.Writer) {
    f = v
}

func exampleF(s string) io.Writer {
    fmt.Println("Received:", s)
    return os.Stdout
}

func main() {
    SetF(exampleF)

    w := f("foo")
    w.Write([]byte("bar"))
}

Go Playground上运行该示例会输出:

Received: foo
bar
英文:

func(*Server) eintefaces.BotInterface is not a nameless function, it's a function type. It's the type of a function that takes *Server as its argument and returns a value of type eintefaces.BotInterface.

botInterface is an unexported variable. Its type is a function type described above.

The SetBotInterface() exported function gives the possibility to set (assign) a value to the unexported botInterface variable. You have to pass a function value of the same type, and it simply assigns it to the unexported variable (you can't access the unexported variable otherwise).

See a similar example with usage:

var f func(string) io.Writer

func SetF(v func(string) io.Writer) {
	f = v
}

func exampleF(s string) io.Writer {
	fmt.Println("Received:", s)
	return os.Stdout
}

func main() {
	SetF(exampleF)

	w := f("foo")
	w.Write([]byte("bar"))
}

Which outputs (try it on the Go Playground):

Received: foo
bar

答案2

得分: 1

这不是匿名函数,而是函数类型。这段代码允许你将自己的函数赋值给一个未导出的botInterface变量(你不能直接从外部更改)在该包中。你可以将任何接受*Server并返回einterface.BotInterface的函数作为参数传递给SetBotInterface。参数然后被设置为botInterface,可能在该包的某个地方被调用。

所以在你的包的某个地方,你可以这样做:

func MyFunc(s *thatpackage.Server) einterface.BotInterface {
 // 在这里编写你的代码...
}

然后稍后像这样将它传递给该包:

thatpackage.SetBotInterface(MyFunc)

// 或者直接传递匿名函数:
thatpackage.SetBotInterface(func (s *thatpackage.Server) einterface.BotInterface {
  // 在这里编写你的代码...
})

注意:我将包含SetBotInterface的包称为thatpackage,因为你的问题中没有提到包的名称。

这种方法经常用于在框架等中实现各种可定制的处理程序。

你可以将你发布的代码理解为这样 - 这样更容易理解其中发生的事情:

type BotInterfaceFuncType = func(*Server) eintefaces.BotInterface 

var botInterface BotInterfaceFuncType

func SetBotInterface(b BotInterfaceFuncType){
   botInterface = b 
}
英文:

It is not anonymous function but function type. This code allows you to assign your own function to an unexported botInterface variable (which you can't directly change from outside) in that package. You pass any function that takes *Server and returns einterface.BotInterface as an argument to SetBotInterface. Argument is then set to botInterface and probably called somewhere in that package.

So somewhere in your package you can do

func MyFunc(s *thatpackage.Server) einterface.BotInterface {
 // your code here...
}

and then later pass it to that package like this:

thatpackage.SetBotInterface(MyFunc)

// or even passing anonymous function directly:
thatpackage.SetBotInterface(func (s *thatpackage.Server) einterface.BotInterface {
  // your code here...
})

Note: I referred to package containing SetBotInterface as thatpackage because name is not known from your question.

This approach is often used to implement various customizable handlers in frameworks, etc.

You can think of code you posted like this - it makes it easier to understand what happens there:

type BotInterfaceFuncType = func(*Server) eintefaces.BotInterface 

var botInterface BotInterfaceFuncType

func SetBotInterface(b BotInterfaceFuncType){
   botInterface = b 
}

huangapple
  • 本文由 发表于 2021年6月24日 14:47:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/68110795.html
匿名

发表评论

匿名网友

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

确定