将函数作为参数传递给另一个函数

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

Passing function as an argument to another function

问题

如何在不传递参数的情况下调用一个函数?

我对Go语言还比较新。SignInHandler函数期望传递一个*gin.Context类型的参数,但在函数调用authHandler.SignInHandler时并没有显式地传递该参数。是否存在一种隐式传递或上下文的特殊情况,我不太确定。


我最初以为是在调用函数,但实际上只是传递函数引用。

main.go

package main

var authHandler *handlers.AuthHandler

func init() {
	ctx := context.Background()
	authHandler = &handlers.AuthHandler{}
}

func main() {
	router := gin.Default()
	router.POST("/signin", authHandler.SignInHandler)
}

auth.go

type AuthHandler struct{}

func (handler *AuthHandler) SignInHandler(c *gin.Context) {

}
英文:

Original

How can go call a function without passing parameters

I am fairly new to go. SignInHandler expect a parameter of type *gin.Context, but this is not explicitly passed during function call authHandler.SignInHandler. Is there some sort of implicit passing or special case for context, I am not sure.


Update

I originally thought that it is calling the function, but it is simply passing the function reference.

main.go

package main

var authHandler *handlers.AuthHandler

func init() {
	ctx := context.Background()
	authHandler = &handlers.AuthHandler{}
}

func main() {
	router := gin.Default()
	router.POST("/signin", authHandler.SignInHandler)
}

auth.go

type AuthHandler struct{}

func (handler *AuthHandler) SignInHandler(c *gin.Context) {

}

答案1

得分: 1

不,Context 参数的处理没有什么特殊之处。它只是像其他参数一样的参数。

router.POST("/signin", authHandler.SignInHandler) 不是对 authHandler.SignInHandler 函数的调用(注意末尾没有 ())。相反,它将函数作为 HandlerFunc 类型 的参数传递给 router.POST(),以便在稍后调用时(处理路由时)使用。

当服务器处理该路由的请求时,处理函数将被运行(由 gin 运行),并且在幕后,它确实会像通常一样使用 Context 参数进行调用。该 Context 将由调用者(通常是中间件或 HTTP 服务器)提供。

在 playground 中有一个简单的演示示例,展示了这个概念,但没有 gin 代码库的复杂性。

英文:

No, there's nothing special in Context argument treatment. It's argument as any other.

router.POST("/signin", authHandler.SignInHandler) is not authHandler.SignInHandler function call (note there are no () at the end). Instead it is passing the function as an argument of HandlerFunc type to router.POST() for later invocation (when handling route).

When server is handling request for that route; handler function will be run (by gin) and under the hood it will indeed be called with the Context argument as usual. That Context will be provided by caller (usually middleware or http server).

See small demonstration in playground that shows this concept without the complexity of gin codebase.

答案2

得分: 1

在你的示例中,该函数不需要参数,因为代码中没有显式调用该函数。函数调用使用调用语法进行,以(开头,以)结尾,参数(如果有)在中间。

在Go语言中,函数是一等值,因此可以引用它们而不调用它们。例如:

func myFunc() {
	fmt.Println("Hello")
}

func main() {
	fmt.Println("- Beginning")

	// 将函数赋值给变量。
	var someFuncVar = myFunc

	fmt.Println("- Middle")

	// 现在调用函数变量。
	someFuncVar()

	fmt.Println("- End")
}

输出:

- Beginning
- Middle
Hello
- End

自己试试

authHandler.SignInHandler 在技术上被称为“方法值”(在这里定义),它是这个概念的稍微高级的版本。通过通过实例(authHandler)引用方法名(SignInHandler),你可以得到一个绑定到特定实例的函数值。

以下是语言规范中的更正式定义:
> 如果表达式 x 的静态类型为 T,并且 M 在类型 T 的方法集中,那么 x.M 被称为方法值。方法值 x.M 是一个函数值,可以使用与调用 x.M 的方法调用相同的参数进行调用。在方法值的评估过程中,表达式 x 被计算并保存;保存的副本稍后将作为接收器在任何调用中使用,这些调用可能在以后执行。

英文:

The function doesn't need a parameter in your example, because that code doesn't explicitly call the function. Function calls happen with the calling syntax, beginning with (, ending with ), with arguments (if any) in between.

Functions are first class values in Go, so you can reference them without calling them. For example:

func myFunc() {
	fmt.Println("Hello")
}

func main() {
	fmt.Println("- Beginning")

	// Assign the function to a variable.
	var someFuncVar = myFunc

	fmt.Println("- Middle")

	// Now call the function variable.
	someFuncVar()

	fmt.Println("- End")
}

Outputs:

- Beginning
- Middle
Hello
- End

Try it yourself

authHandler.SignInHandler is technically called a "method value" (defined here), which is a slightly more advanced version of this. By referencing the method name (SignInHandler) through an instance (authHandler), you get a function value which is bound to that particular instance.

Here's a more formal definition from the language spec:
> If the expression x has static type T and M is in the method set of type T, x.M is called a method value. The method value x.M is a function value that is callable with the same arguments as a method call of x.M. The expression x is evaluated and saved during the evaluation of the method value; the saved copy is then used as the receiver in any calls, which may be executed later.

huangapple
  • 本文由 发表于 2022年12月23日 08:38:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/74895137.html
匿名

发表评论

匿名网友

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

确定