函数可以作为参数传递吗?

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

Can functions be passed as parameters?

问题

在Java中,我可以像这样做:

derp(new Runnable { public void run () { /* run this sometime later */ } })

并且稍后可以“运行”方法中的代码。处理这种情况有点麻烦(匿名内部类),但是可以实现。

Go语言是否有类似的功能,可以方便地将函数/回调作为参数传递?

英文:

In Java I can do something like

derp(new Runnable { public void run () { /* run this sometime later */ } })

and "run" the code in the method later. It's a pain to handle (anonymous inner class), but it can be done.

Does Go have something that can facilitate a function/callback being passed in as a parameter?

答案1

得分: 334

是的,考虑一些这些例子:

package main

import "fmt"

// convert types take an int and return a string value.
type convert func(int) string

// value implements convert, returning x as string.
func value(x int) string {
    return fmt.Sprintf("%v", x)
}

// quote123 passes 123 to convert func and returns quoted string.
func quote123(fn convert) string {
    return fmt.Sprintf("%q", fn(123))
}

func main() {
    var result string
    
    result = value(123)
    fmt.Println(result)
    // Output: 123
    
    result = quote123(value)
    fmt.Println(result)
    // Output: "123"
    
    result = quote123(func(x int) string { return fmt.Sprintf("%b", x) })
    fmt.Println(result)
    // Output: "1111011"
    
    foo := func(x int) string { return "foo" }
    result = quote123(foo)
    fmt.Println(result)
    // Output: "foo"
    
    _ = convert(foo) // confirm foo satisfies convert at runtime
    
    // fails due to argument type
    // _ = convert(func(x float64) string { return "" })
}

Play: http://play.golang.org/p/XNMtrDUDS0

Tour: https://tour.golang.org/moretypes/25 (Function Closures)

英文:

Yes, consider some of these examples:

package main

import "fmt"

// convert types take an int and return a string value.
type convert func(int) string

// value implements convert, returning x as string.
func value(x int) string {
    return fmt.Sprintf("%v", x)
}

// quote123 passes 123 to convert func and returns quoted string.
func quote123(fn convert) string {
    return fmt.Sprintf("%q", fn(123))
}

func main() {
    var result string
    
    result = value(123)
    fmt.Println(result)
    // Output: 123
    
    result = quote123(value)
    fmt.Println(result)
    // Output: "123"
    
    result = quote123(func(x int) string { return fmt.Sprintf("%b", x) })
    fmt.Println(result)
    // Output: "1111011"
    
    foo := func(x int) string { return "foo" }
    result = quote123(foo)
    fmt.Println(result)
    // Output: "foo"
    
    _ = convert(foo) // confirm foo satisfies convert at runtime
    
    // fails due to argument type
    // _ = convert(func(x float64) string { return "" })
}

Play: http://play.golang.org/p/XNMtrDUDS0

Tour: https://tour.golang.org/moretypes/25 (Function Closures)

答案2

得分: 61

你可以将函数作为参数传递给Go函数。以下是将函数作为参数传递给另一个Go函数的示例:

package main

import "fmt"

type fn func(int) 

func myfn1(i int) {
    fmt.Printf("\ni is %v", i)
}
func myfn2(i int) {
    fmt.Printf("\ni is %v", i)
}
func test(f fn, val int) {
    f(val)
}
func main() {
    test(myfn1, 123)
    test(myfn2, 321)
}

你可以在此处尝试:https://play.golang.org/p/9mAOUWGp0k

英文:

You can pass function as parameter to a Go function. Here is an example of passing function as parameter to another Go function:

package main

import "fmt"

type fn func(int) 

func myfn1(i int) {
	fmt.Printf("\ni is %v", i)
}
func myfn2(i int) {
	fmt.Printf("\ni is %v", i)
}
func test(f fn, val int) {
	f(val)
}
func main() {
	test(myfn1, 123)
	test(myfn2, 321)
}

You can try this out at: https://play.golang.org/p/9mAOUWGp0k

答案3

得分: 27

这是Go语言中的示例"Map"实现。希望这对你有所帮助!!

func square(num int) int {
    return num * num
}

func mapper(f func(int) int, alist []int) []int {
    var a = make([]int, len(alist), len(alist))
    for index, val := range alist {

        a[index] = f(val)
    }
    return a
}

func main() {
    alist := []int{4, 5, 6, 7}
    result := mapper(square, alist)
    fmt.Println(result)

}
英文:

Here is the sample "Map" implementation in Go. Hope this helps!!

func square(num int) int {
	return num * num
}

func mapper(f func(int) int, alist []int) []int {
	var a = make([]int, len(alist), len(alist))
	for index, val := range alist {

		a[index] = f(val)
	}
	return a
}

func main() {
	alist := []int{4, 5, 6, 7}
	result := mapper(square, alist)
	fmt.Println(result)

}

答案4

得分: 7

这是一个简单的例子:

    package main

    import "fmt"

    func plusTwo() (func(v int) (int)) {
        return func(v int) (int) {
            return v+2
        }
    }

    func plusX(x int) (func(v int) (int)) {
       return func(v int) (int) {
           return v+x
       }
    }

    func main() {
        p := plusTwo()
        fmt.Printf("3+2: %d\n", p(3))

        px := plusX(3)
        fmt.Printf("3+3: %d\n", px(3))
    }
英文:

Here is a simple example:

    package main

    import "fmt"

    func plusTwo() (func(v int) (int)) {
	    return func(v int) (int) {
		    return v+2
	    }
    }

    func plusX(x int) (func(v int) (int)) {
	   return func(v int) (int) {
           return v+x
	   }
    }

    func main() {
	    p := plusTwo()
	    fmt.Printf("3+2: %d\n", p(3))

	    px := plusX(3)
	    fmt.Printf("3+3: %d\n", px(3))
    }

答案5

得分: 5

这是我能想到的最简单的方法。

package main

import "fmt"

func main() {
    g := greeting
    getFunc(g)
}

func getFunc(f func()) {
    f()
}

func greeting() {
    fmt.Println("Hello")
}
英文:

This is the simplest way I can come with.

package main

import "fmt"

func main() {
    g := greeting
    getFunc(g)
}

func getFunc(f func()) {
    f()
}

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

答案6

得分: 2

我希望下面的示例能提供更清晰的说明。

package main

type EmployeeManager struct{
    category         string
    city             string
    calculateSalary  func() int64
}


func NewEmployeeManager() (*EmployeeManager,error){

    return &EmployeeManager{
        category : "MANAGEMENT",
        city : "NY",
        calculateSalary: func() int64 {
            var calculatedSalary int64
            // 一些计算公式
            return calculatedSalary
        },
    },nil
}

func (self *EmployeeManager) emWithSalaryCalculation(){
    self.calculateSalary = func() int64 {
        var calculatedSalary int64
        // 一些新的计算公式
        return calculatedSalary
    }
}

func updateEmployeeInfo(em EmployeeManager){
    // 一些代码
}

func processEmployee(){
    updateEmployeeInfo(struct {
        category        string
        city            string
        calculateSalary func() int64
    }{category: "", city: "", calculateSalary: func() int64 {
        var calculatedSalary int64
        // 一些新的计算公式
        return calculatedSalary
    }})
}
英文:

I hope the below example will provide more clarity.

package main

type EmployeeManager struct{
	category 			string
	city				string
	calculateSalary 	func() int64
}


func NewEmployeeManager() (*EmployeeManager,error){

	return &EmployeeManager{
		category : "MANAGEMENT",
		city : "NY",
		calculateSalary: func() int64 {
			var calculatedSalary int64
			// some formula
			return calculatedSalary
		},
	},nil
}

func (self *EmployeeManager) emWithSalaryCalculation(){
	self.calculateSalary = func() int64 {
		var calculatedSalary int64
		// some new formula
		return calculatedSalary
	}
}

func updateEmployeeInfo(em EmployeeManager){
	// Some code
}

func processEmployee(){
	updateEmployeeInfo(struct {
		category        string
		city            string
		calculateSalary func() int64
	}{category: "", city: "", calculateSalary: func() int64 {
		var calculatedSalary int64
		// some new formula
		return calculatedSalary
	}})
}

答案7

得分: 1

你也可以传递一个结构体的函数,例如:

    package main
    // 定义结构体
    type Apple struct {}
    
    // 返回苹果的颜色
    func (Apple) GetColor() string {
         return "红色" 
    }
    
    func main () {
    	// 实例化
    	myApple := Apple{}
    	
        // 将函数放入变量中
    	theFunc := myApple.GetColor
    	
        // 将变量作为函数执行
    	color := theFunc()
    
    	print(color)
    }

输出将会是 "红色",在 playground 上查看

英文:

You can also pass the function of a struct, like:

    package main
    // define struct
    type Apple struct {}
    
    // return apple's color
    func (Apple) GetColor() string {
         return "Red" 
    }
    
    func main () {
    	// instantiate
    	myApple := Apple{}
    	
        // put the func in a variable
    	theFunc := myApple.GetColor
    	
        // execute the variable as a function
    	color := theFunc()
    
    	print(color)
    }

output will be "Red", check on the playground

答案8

得分: -3

是的,Go语言确实支持一等函数。

请参阅文章《Go语言中的一等函数》(链接)获取有用的链接。

英文:

Yes Go does accept first-class functions.

See the article "First Class Functions in Go" for useful links.

huangapple
  • 本文由 发表于 2012年9月30日 02:45:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/12655464.html
匿名

发表评论

匿名网友

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

确定