2010-08-30 11 views
36

Stavo imparando i puntatori in Google Go. E è riuscito a scrivere qualcosa del tipo,Possiamo avere dei puntatori di funzione in 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 
} 

C'è un modo per dichiarare il puntatore di funzione senza definirlo come fatto sopra? Possiamo scrivere qualcosa come facciamo in C?

ad es. void (*pfunc)(void);

+5

io non ne so abbastanza su Go per rispondere alla tua domanda, ma ho un counterquestion: perché sarebbe vuoi avere dei puntatori di funzione quando Go ha le funzioni corrette di prima classe? –

+1

Suppongo che sia più una questione educativa. Ho uno sfondo in C e ho appena iniziato a conoscere Go. Ho notato che Go ha dei puntatori simili a C e quindi desideravo sapere se i puntatori di funzione sono possibili in Go e se sì, come dichiararli. – Kevin

risposta

50

Funziona se si utilizza la firma. Non c'è puntatore.

type HelloFunc func(string) 

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

func main() { 
    var hf HelloFunc 

    hf = SayHello 

    hf("world") 
} 

In alternativa è possibile utilizzare direttamente la firma della funzione, senza dichiarare un nuovo tipo.

+0

Grazie Mue per aver spiegato l'uso del "tipo" per le funzioni. – Kevin

23

Go non ha la stessa sintassi per i puntatori di funzione come C e C++. C'è una buona spiegazione per quello su Go blog. Comprensibilmente gli autori di Go hanno pensato alla sintassi di C per i puntatori di funzioni troppo simili ai puntatori regolari, quindi in breve hanno deciso di rendere espliciti i puntatori di funzione; cioè più leggibile.

Ecco un esempio che ho scritto. Si noti come il parametro fp sia definito in calculate() e l'altro esempio riportato di seguito che mostra come è possibile creare un puntatore a funzione in un tipo e utilizzarlo in una funzione (la funzione di calcolo commentata).

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 
} 

Il parametro fp è definito come una funzione che prende due int e restituisce un singolo int. Questo è in qualche modo la stessa cosa menzionata Mue ma mostra un diverso esempio di utilizzo.

+0

Grazie Hannson. – Kevin

+0

Penso che tu stia fraintendendo quel post sul blog. Non sta dicendo che i puntatori di funzione non sono "permessi", piuttosto che hanno una diversa sintassi di dichiarazione in C. – poolie

+0

Non stavo leggendo male; Ho appena avuto una scelta scadente di parole :) – hannson

4

Si potrebbe fare così:

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

Se la funzione ha argomenti e per esempio un valore di ritorno, sarebbe simile:

func hello(name string) int{ 

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

e la variabile sarà simile:

var pfunc func(string)int 
Problemi correlati