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

在Java中,我可以这样做

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

然后在方法中“运行”代码。处理起来很麻烦(匿名内部类),但这是可以做到的。

Go是否有一些可以方便函数/回调作为参数传递的东西?

220047 次浏览

是的,Go确实接受一类函数。

有关有用的链接,请参阅文章《围棋中的第一类函数》

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

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 "" })
}

游戏:http://play.golang.org/p/XNMtrDUDS0

https://tour.golang.org/moretypes/25(函数闭包)

这里有一个简单的例子:

    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))
}

你可以把函数作为参数传递给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处尝试

下面是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)


}

我希望下面的例子能更清楚地说明问题。

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
}})
}

你也可以传递一个struct的函数,比如:

    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)
}

输出将是"Red", 检查操场

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

package main


import "fmt"


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


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


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