2014-03-25 15 views
7

Das ist vielleicht keine so gute Frage, da ich keine kompilierte Sprache kenne, die diese Funktion unterstützt, aber da Go mich ständig überrascht, werde ich es trotzdem fragen:Unterstützt Go Operator-Typvariablen?

Für meine eigene Praxis Ich schreibe ein kleines Taschenrechnerprogramm in Go. Ich frage mich, ob es einen Weg gibt, kann ich eine Variable vom Typ „Operator“, so dass ich könnte zum Beispiel erklärt und zuordnen, schreiben:

var o Operator 

o = + 

var o1 Operator 

o1 =/

und schreibe Funktion wie diese

func DoOperation(a,b int,o Operator) int{ 

    return a o b 

} 

(Nein, ich frage nicht nach Überlastung des Bedieners.)

Offhand, ich kenne keine kompilierte Sprache, die so etwas unterstützt (ich bin kein Experte in diesem). Ich habe mir die Dokumente unter den Operatoren angeschaut und nichts gefunden. Kann mich das nochmal überraschen?

Edit: Die akzeptierte Antwort heißt es, dass Haskell dies unterstützt,

+2

Jede dieser besonderen Grund wurde downvoted? Da Haskell dies unterstützt, ist es laut @ tomwildes Antwort keine dumme Frage und ich habe mir die Dokumente unter Operatoren angeschaut und nichts gefunden, aber Go scheint seinen Anteil an "Ostereiern" zu haben – Vector

+0

Io kann sowas machen. – dethtron5000

+0

@ dethtron5000 - interessant. Ich habe noch nie von 'Io' gehört, nur nachgeschaut - keine Mainstream-Sprache, denke ich ... :) Ich sehe, dass es in einer virtuellen Maschine läuft. Kompiliert es zu etwas wie Java Bytecode oder MSIL? – Vector

Antwort

7

Nein, Go-Betreiber keine Funktionen sind und daher keine gültigen rechten Ausdrücke. Sie arbeiten auf generische Weise, z.B. Der Plus-Operator funktioniert bei allen numerischen Typen und die Infix-Notation a la haskell wird ebenfalls nicht unterstützt.

Sie müssten Ihre eigene "soft" -generische Additionsfunktion mit Reflektion schreiben.

Eine kompilierte Sprache, die alle Ihre Anforderungen abdeckt, ist Haskell.

5

Sie können nicht genau das tun, was Sie sagen, aber Sie können stattdessen Funktionen verwenden. Sie müssen Funktionen für jeden Operator schreiben, aber das ist relativ wenig Code.

type BinaryOperator func(a, b int) int 

func OpAdd(a, b int) int { return a + b } 
func OpSub(a, b int) int { return a - b } 

func ApplyBinaryOperator(a, b int, op BinaryOperator) int { 
    return op(a, b) 
} 
+0

Entschuldigung, ich kann beide Antworten nicht akzeptieren. Aber @tomwilde war zuerst und technisch detaillierter. Aber Ihre Workaround ist eine ** ausgezeichnete ** Idee, die ich wahrscheinlich implementieren werde. – Vector

+4

Beachten Sie, dass dieses Beispiel weiterhin funktioniert, wenn Sie BinaryOperator() um die Funktionsliterale ablegen: var OpAdd = func (a, b int) int {return a + b} und ähnlich für OpSub. –

+0

Danke Russ! Ich habe den Code geändert, um Ihren Vorschlag zu übernehmen. –

0

von einem oop Hintergrund kommend ich tun dies begann:

package main 

import "fmt" 
type MyInt int64 

func (i * MyInt) Add(n MyInt) * MyInt { 
    *i += n 
    return i 
} 

func (i MyInt) String() string { 
    v := int64(i) 
    return fmt.Sprintf("0x%x (%d)", v, v) 
} 

func main() { 
    x := MyInt(10) 
    x.Add(10).Add(20).Add(30) 
    fmt.Println("x = ", x) 
} 
+0

Ich bevorzuge den Ansatz in @ Anonymous Antwort - es ist nichts anderes als gute altmodische Funktionszeiger, nur es Go-Stil (so dass es klar und einfach) und halten es allgemein, obwohl Ihr Ansatz könnte auch mit einem ähnlichen Design-Muster arbeiten. Siehe auch [Wie konvertiert man einen int-Wert in einen String?] (Http://stackoverflow.com/questions/10105935/how-to-convert-a-int-value-to-string-in-go) – Vector