2010-08-30 9 views
36

Ich habe in Google Go über Zeiger gelernt. Und schaffte es, etwas zu schreiben wie,Können wir Funktionszeiger in Google Go haben?

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 
} 

Gibt es eine Möglichkeit, den Funktionszeiger zu deklarieren, ohne es wie oben getan zu definieren? Können wir etwas schreiben, wie wir es in C machen?

z.B. void (*pfunc)(void);

+5

ich über Go nicht genug weiß um Ihre Frage zu beantworten, aber ich habe eine Gegenfrage: Warum sollte Sie möchten Funktionszeiger haben, wenn Go über erstklassige Funktionen verfügt? –

+1

Ich denke, es ist eher eine pädagogische Frage. Ich habe einen Hintergrund in C und habe gerade angefangen, etwas über Go zu lernen. Ich habe bemerkt, dass Go Zeiger ähnlich wie C hat und wollte daher wissen, ob Funktionszeiger in Go möglich sind und, wenn ja, wie man sie deklariert. – Kevin

Antwort

50

Es funktioniert, wenn Sie die Signatur verwenden. Es gibt keinen Zeiger.

type HelloFunc func(string) 

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

func main() { 
    var hf HelloFunc 

    hf = SayHello 

    hf("world") 
} 

Alternativ können Sie die Funktionssignatur direkt verwenden, ohne einen neuen Typ zu deklarieren.

+0

Danke Mue für die Erklärung der Verwendung des "Typs" für Funktionen. – Kevin

23

Go hat nicht die gleiche Syntax für Funktionszeiger wie C und C++. Dafür gibt es eine ziemlich gute Erklärung auf der Go blog. Verständlicherweise dachten die Go-Autoren, dass die C-Syntax für Funktionszeiger zu normalen Zeigern zu ähnlich ist. Kurz gesagt, entschieden sie sich dafür, Funktionszeiger explizit zu machen; d.h. besser lesbar.

Hier ist ein Beispiel, das ich schrieb. Beachten Sie, wie der fp Parameter in calculate() definiert ist und das andere Beispiel unten zeigt, wie Sie einen Funktionszeiger zu einem Typ machen und in einer Funktion verwenden können (die kommentierte Berechnungsfunktion).

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 Der Parameter wird definiert als eine Funktion, die zwei ints nimmt und gibt einen einzelnen Int. Dies ist etwas das gleiche, Mue erwähnt, aber zeigt ein anderes Anwendungsbeispiel.

+0

Danke Hannson. – Kevin

+0

Ich denke, Sie lesen diesen Blogpost falsch. Es heißt nicht, dass Funktionszeiger nicht "erlaubt" sind, sondern dass sie eine andere Deklarationssyntax als in C haben. – poolie

+0

Ich habe nicht falsch gelesen; Ich hatte nur eine schlechte Wortwahl :) – hannson

4

Man könnte es wie folgt tun:

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

Wenn Ihre Funktion Argumente hat und z.B. ein Rückgabewert, würde es so aussehen:

func hello(name string) int{ 

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

und die Variable würde wie folgt aussehen:

var pfunc func(string)int 
Verwandte Themen