我们可以在Go中使用函数指针吗?

时间:2010-08-30 15:24:43

标签: go

我正在学习Go中的指针。并设法编写类似的内容:

func hello(){

       fmt.Println("Hello World")
}

func main(){

       pfunc := hello     //pfunc is a pointer to the function "hello"
       pfunc()            //calling pfunc prints "Hello World" similar to hello function
}

有没有办法声明函数指针而不像上面那样定义它? 我们可以写一些像C一样的东西吗?

e.g。 void (*pfunc)(void);

6 个答案:

答案 0 :(得分:65)

如果您使用签名,它会起作用。没有指针。

type HelloFunc func(string)

func SayHello(to string) {
    fmt.Printf("Hello, %s!\n", to)
}

func main() {
    var hf HelloFunc

    hf = SayHello

    hf("world")
}

或者,您可以直接使用函数签名,而无需声明新类型。

答案 1 :(得分:29)

Go与C和C ++没有相同的函数指针语法。在Go blog上有一个非常好的解释。可以理解的是,Go的作者认为C的函数指针语法与常规指针太相似,所以简而言之,他们决定使函数指针显式化;即更具可读性。

这是我写的一个例子。注意fp参数是如何在calculate()中定义的,下面的另一个例子向您展示如何将函数指针转换为类型并在函数中使用它(注释的计算函数)。

package main

import "fmt"

type ArithOp func(int, int)int

func main() {
    calculate(Plus)
    calculate(Minus)
    calculate(Multiply)
}

func calculate(fp func(int, int)int) {
    ans := fp(3,2)
    fmt.Printf("\n%v\n", ans) 
}

// This is the same function but uses the type/fp defined above
// 
// func calculate (fp ArithOp) {
//     ans := fp(3,2)
//     fmt.Printf("\n%v\n", ans) 
// }

func Plus(a, b int) int {
    return a + b
}

func Minus(a, b int) int {
    return a - b
}

func Multiply(a,b int) int {
    return a * b
}

fp参数定义为一个带两个整数并返回单个int的函数。这与Mue提到的有些相同,但显示了不同的用法示例。

答案 2 :(得分:4)

你可以这样做:

package main

import "fmt"

func hello(){

       fmt.Println("Hello World")
}

func main(){
       var pfunc func()
       pfunc = hello     //pfunc is a pointer to the function "hello"
       pfunc()            
}

如果你的函数有参数,例如返回值,它看起来像:

func hello(name string) int{

       fmt.Println("Hello %s", name)
       return 0
}

并且变量看起来像:

  var pfunc func(string)int

答案 3 :(得分:0)

另一种处理方法是定义一个接口

type command interface {
      DoLoop()
}

实现一个实现它的结构

type Delete struct {
      instance string
}

func (dev Delete) DoLoop() {
      fmt.Println("input: delete ")
}

创建包含结构的地图

 mainFuncTable = make(map[string]command)
 mainFuncTable["delete"] = Delete{"new"}

调用函数

func route(command string) {
      cmd := mainFuncTable[command]
      cmd.DoLoop()
}

这是间接的,但是有效

答案 4 :(得分:0)

函数也是Go中的一种类型。因此,您基本上可以创建签名类型为func的变量。所以下面的方法会起作用;

var pfunc func(string)

此变量可以指向以字符串为参数且不返回任何内容的任何函数。下面的代码行之有效。

package main

import "fmt"

func SayHello(to string) {
    fmt.Printf("Hello, %s!\n", to)
}

func main() {
    var pfunc func(string)

    pfunc = SayHello

    pfunc("world")
}

答案 5 :(得分:0)

基于数组的函数指针解决方案

package main

import (
    "fmt"
)

type pfunc func(string, int)int

func testCase1(toStr string, toInt int)int {
    fmt.Printf("1st Function Call %s %d\n",toStr, toInt)
    return toInt
}

func testCase2(toStr string, toInt int)int {
    fmt.Printf("2nd Function Call %s %d\n",toStr, toInt)
    return toInt
}

func testCase3(toStr string, toInt int)int {
    fmt.Printf("3rd Function Call %s %d\n",toStr, toInt)
    return toInt
}

func main() {
        
    funcArray := []pfunc{testCase1,testCase2,testCase3} 
    
    for n:=range funcArray {
        result := funcArray[n]("Test", n)
        fmt.Printf("Run Test Case #%d reference %v result %d\n",n, funcArray[n], result)
    }
}