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

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

Can functions be passed as parameters?

问题

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

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

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

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

英文:

In Java I can do something like

  1. 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

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

  1. package main
  2. import "fmt"
  3. // convert types take an int and return a string value.
  4. type convert func(int) string
  5. // value implements convert, returning x as string.
  6. func value(x int) string {
  7. return fmt.Sprintf("%v", x)
  8. }
  9. // quote123 passes 123 to convert func and returns quoted string.
  10. func quote123(fn convert) string {
  11. return fmt.Sprintf("%q", fn(123))
  12. }
  13. func main() {
  14. var result string
  15. result = value(123)
  16. fmt.Println(result)
  17. // Output: 123
  18. result = quote123(value)
  19. fmt.Println(result)
  20. // Output: "123"
  21. result = quote123(func(x int) string { return fmt.Sprintf("%b", x) })
  22. fmt.Println(result)
  23. // Output: "1111011"
  24. foo := func(x int) string { return "foo" }
  25. result = quote123(foo)
  26. fmt.Println(result)
  27. // Output: "foo"
  28. _ = convert(foo) // confirm foo satisfies convert at runtime
  29. // fails due to argument type
  30. // _ = convert(func(x float64) string { return "" })
  31. }

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

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

英文:

Yes, consider some of these examples:

  1. package main
  2. import "fmt"
  3. // convert types take an int and return a string value.
  4. type convert func(int) string
  5. // value implements convert, returning x as string.
  6. func value(x int) string {
  7. return fmt.Sprintf("%v", x)
  8. }
  9. // quote123 passes 123 to convert func and returns quoted string.
  10. func quote123(fn convert) string {
  11. return fmt.Sprintf("%q", fn(123))
  12. }
  13. func main() {
  14. var result string
  15. result = value(123)
  16. fmt.Println(result)
  17. // Output: 123
  18. result = quote123(value)
  19. fmt.Println(result)
  20. // Output: "123"
  21. result = quote123(func(x int) string { return fmt.Sprintf("%b", x) })
  22. fmt.Println(result)
  23. // Output: "1111011"
  24. foo := func(x int) string { return "foo" }
  25. result = quote123(foo)
  26. fmt.Println(result)
  27. // Output: "foo"
  28. _ = convert(foo) // confirm foo satisfies convert at runtime
  29. // fails due to argument type
  30. // _ = convert(func(x float64) string { return "" })
  31. }

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

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

答案2

得分: 61

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

  1. package main
  2. import "fmt"
  3. type fn func(int)
  4. func myfn1(i int) {
  5. fmt.Printf("\ni is %v", i)
  6. }
  7. func myfn2(i int) {
  8. fmt.Printf("\ni is %v", i)
  9. }
  10. func test(f fn, val int) {
  11. f(val)
  12. }
  13. func main() {
  14. test(myfn1, 123)
  15. test(myfn2, 321)
  16. }

你可以在此处尝试: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:

  1. package main
  2. import "fmt"
  3. type fn func(int)
  4. func myfn1(i int) {
  5. fmt.Printf("\ni is %v", i)
  6. }
  7. func myfn2(i int) {
  8. fmt.Printf("\ni is %v", i)
  9. }
  10. func test(f fn, val int) {
  11. f(val)
  12. }
  13. func main() {
  14. test(myfn1, 123)
  15. test(myfn2, 321)
  16. }

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

答案3

得分: 27

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

  1. func square(num int) int {
  2. return num * num
  3. }
  4. func mapper(f func(int) int, alist []int) []int {
  5. var a = make([]int, len(alist), len(alist))
  6. for index, val := range alist {
  7. a[index] = f(val)
  8. }
  9. return a
  10. }
  11. func main() {
  12. alist := []int{4, 5, 6, 7}
  13. result := mapper(square, alist)
  14. fmt.Println(result)
  15. }
英文:

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

  1. func square(num int) int {
  2. return num * num
  3. }
  4. func mapper(f func(int) int, alist []int) []int {
  5. var a = make([]int, len(alist), len(alist))
  6. for index, val := range alist {
  7. a[index] = f(val)
  8. }
  9. return a
  10. }
  11. func main() {
  12. alist := []int{4, 5, 6, 7}
  13. result := mapper(square, alist)
  14. fmt.Println(result)
  15. }

答案4

得分: 7

这是一个简单的例子:

  1. package main
  2. import "fmt"
  3. func plusTwo() (func(v int) (int)) {
  4. return func(v int) (int) {
  5. return v+2
  6. }
  7. }
  8. func plusX(x int) (func(v int) (int)) {
  9. return func(v int) (int) {
  10. return v+x
  11. }
  12. }
  13. func main() {
  14. p := plusTwo()
  15. fmt.Printf("3+2: %d\n", p(3))
  16. px := plusX(3)
  17. fmt.Printf("3+3: %d\n", px(3))
  18. }
英文:

Here is a simple example:

  1. package main
  2. import "fmt"
  3. func plusTwo() (func(v int) (int)) {
  4. return func(v int) (int) {
  5. return v+2
  6. }
  7. }
  8. func plusX(x int) (func(v int) (int)) {
  9. return func(v int) (int) {
  10. return v+x
  11. }
  12. }
  13. func main() {
  14. p := plusTwo()
  15. fmt.Printf("3+2: %d\n", p(3))
  16. px := plusX(3)
  17. fmt.Printf("3+3: %d\n", px(3))
  18. }

答案5

得分: 5

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

  1. package main
  2. import "fmt"
  3. func main() {
  4. g := greeting
  5. getFunc(g)
  6. }
  7. func getFunc(f func()) {
  8. f()
  9. }
  10. func greeting() {
  11. fmt.Println("Hello")
  12. }
英文:

This is the simplest way I can come with.

  1. package main
  2. import "fmt"
  3. func main() {
  4. g := greeting
  5. getFunc(g)
  6. }
  7. func getFunc(f func()) {
  8. f()
  9. }
  10. func greeting() {
  11. fmt.Println("Hello")
  12. }

答案6

得分: 2

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

  1. package main
  2. type EmployeeManager struct{
  3. category string
  4. city string
  5. calculateSalary func() int64
  6. }
  7. func NewEmployeeManager() (*EmployeeManager,error){
  8. return &EmployeeManager{
  9. category : "MANAGEMENT",
  10. city : "NY",
  11. calculateSalary: func() int64 {
  12. var calculatedSalary int64
  13. // 一些计算公式
  14. return calculatedSalary
  15. },
  16. },nil
  17. }
  18. func (self *EmployeeManager) emWithSalaryCalculation(){
  19. self.calculateSalary = func() int64 {
  20. var calculatedSalary int64
  21. // 一些新的计算公式
  22. return calculatedSalary
  23. }
  24. }
  25. func updateEmployeeInfo(em EmployeeManager){
  26. // 一些代码
  27. }
  28. func processEmployee(){
  29. updateEmployeeInfo(struct {
  30. category string
  31. city string
  32. calculateSalary func() int64
  33. }{category: "", city: "", calculateSalary: func() int64 {
  34. var calculatedSalary int64
  35. // 一些新的计算公式
  36. return calculatedSalary
  37. }})
  38. }
英文:

I hope the below example will provide more clarity.

  1. package main
  2. type EmployeeManager struct{
  3. category string
  4. city string
  5. calculateSalary func() int64
  6. }
  7. func NewEmployeeManager() (*EmployeeManager,error){
  8. return &EmployeeManager{
  9. category : "MANAGEMENT",
  10. city : "NY",
  11. calculateSalary: func() int64 {
  12. var calculatedSalary int64
  13. // some formula
  14. return calculatedSalary
  15. },
  16. },nil
  17. }
  18. func (self *EmployeeManager) emWithSalaryCalculation(){
  19. self.calculateSalary = func() int64 {
  20. var calculatedSalary int64
  21. // some new formula
  22. return calculatedSalary
  23. }
  24. }
  25. func updateEmployeeInfo(em EmployeeManager){
  26. // Some code
  27. }
  28. func processEmployee(){
  29. updateEmployeeInfo(struct {
  30. category string
  31. city string
  32. calculateSalary func() int64
  33. }{category: "", city: "", calculateSalary: func() int64 {
  34. var calculatedSalary int64
  35. // some new formula
  36. return calculatedSalary
  37. }})
  38. }

答案7

得分: 1

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

  1. package main
  2. // 定义结构体
  3. type Apple struct {}
  4. // 返回苹果的颜色
  5. func (Apple) GetColor() string {
  6. return "红色"
  7. }
  8. func main () {
  9. // 实例化
  10. myApple := Apple{}
  11. // 将函数放入变量中
  12. theFunc := myApple.GetColor
  13. // 将变量作为函数执行
  14. color := theFunc()
  15. print(color)
  16. }

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

英文:

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

  1. package main
  2. // define struct
  3. type Apple struct {}
  4. // return apple's color
  5. func (Apple) GetColor() string {
  6. return "Red"
  7. }
  8. func main () {
  9. // instantiate
  10. myApple := Apple{}
  11. // put the func in a variable
  12. theFunc := myApple.GetColor
  13. // execute the variable as a function
  14. color := theFunc()
  15. print(color)
  16. }

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:

确定