2010-08-30 9 views
36

Estaba aprendiendo sobre punteros en Google Go. Y logró escribir algo como,¿Podemos tener indicadores de función en Google 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 
} 

¿Existe una forma de declarar el puntero de función sin definirlo como se ha hecho anteriormente? ¿Podemos escribir algo como lo hacemos en C?

p. Ej. void (*pfunc)(void);

+5

No sé lo suficiente sobre Vaya a responder a su pregunta, pero tengo una contrapregunta: ¿por qué ¿Quieres tener punteros de función cuando Go tiene funciones de primera clase? –

+1

Supongo que es más una cuestión educativa. Tengo experiencia en C y recién comencé a aprender sobre Go. Noté que Go tiene punteros similares a C y quería saber si los punteros a función son posibles en Go y, en caso afirmativo, cómo declararlos. – Kevin

Respuesta

50

Funciona si está utilizando la firma. No hay puntero

type HelloFunc func(string) 

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

func main() { 
    var hf HelloFunc 

    hf = SayHello 

    hf("world") 
} 

Como alternativa, puede utilizar la firma de función directamente, sin declarar un tipo nuevo.

+0

Gracias Mue por explicar el uso del "tipo" para las funciones. – Kevin

23

Go no tiene la misma sintaxis para los punteros de funciones que C y C++. Hay una buena explicación para eso en el Go blog. Es comprensible que los autores de Go pensaran que la sintaxis de C para los indicadores de función era muy similar a los indicadores regulares, por lo que decidieron hacer explícitos los indicadores de función; es decir, más legible

Aquí hay un ejemplo que escribí. Observe cómo se define el parámetro fp en calculate() y el otro ejemplo a continuación que muestra cómo puede convertir un puntero de función en un tipo y usarlo en una función (la función de cálculo comentada).

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 
} 

El parámetro fp se define como una función que toma dos enteros y devuelve un solo int. Esto es algo similar a Mue mencionado, pero muestra un ejemplo de uso diferente.

+0

Gracias Hannson. – Kevin

+0

Creo que estás malinterpretando esa publicación de blog. No está diciendo que los punteros a las funciones no están "permitidos", sino que tienen una sintaxis de declaración diferente en C. – poolie

+0

No estaba malinterpretando; Simplemente tuve una mala elección de palabras :) – hannson

4

Se podía hacerlo de esta manera:

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

Si su función tiene argumentos y, por ejemplo, un valor de retorno, que se vería así:

func hello(name string) int{ 

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

y la variable se vería así:

var pfunc func(string)int 
Cuestiones relacionadas