2013-10-26 11 views
21

Gibt es eine Möglichkeit, den Standardwert in Go's Funktion anzugeben? Ich versuche, dies in der Dokumentation zu finden, aber ich kann nichts finden, das angibt, dass dies überhaupt möglich ist.Standardwert in Go's Methode

func SaySomething(i string = "Hello")(string){ 
... 
} 

Antwort

33

NO, aber es gibt einige andere Optionen, Standardwert zu implementieren. Es gibt einige good blog posts zum Thema, aber hier sind einige spezifische Beispiele.


Option 1: Der Anrufer Standardwerte

// Both parameters are optional, use empty string for default value 
func Concat1(a string, b int) string { 
    if a == "" { 
    a = "default-a" 
    } 
    if b == 0 { 
    b = 5 
    } 

    return fmt.Sprintf("%s%d", a, b) 
} 


Option 2 zu verwenden, wählt: Ende Ein einzelner optionaler Parameter

// a is required, b is optional. 
// Only the first value in b_optional will be used. 
func Concat2(a string, b_optional ...int) string { 
    b := 5 
    if len(b_optional) > 0 { 
    b = b_optional[0] 
    } 

    return fmt.Sprintf("%s%d", a, b) 
} 


Option 3: A Config struct

// A declarative default value syntax 
// Empty values will be replaced with defaults 
type Parameters struct { 
    A string `default:"default-a"` // this only works with strings 
    B string // default is 5 
} 

func Concat3(prm Parameters) string { 
    typ := reflect.TypeOf(prm) 

    if prm.A == "" { 
    f, _ := typ.FieldByName("A") 
    prm.A = f.Tag.Get("default") 
    } 

    if prm.B == 0 { 
    prm.B = 5 
    } 

    return fmt.Sprintf("%s%d", prm.A, prm.B) 
} 


Option 4: Voll variadische Argument Parsen (JavaScript Stil)

func Concat4(args ...interface{}) string { 
    a := "default-a" 
    b := 5 

    for _, arg := range args { 
    switch t := arg.(type) { 
     case string: 
     a = t 
     case int: 
     b = t 
     default: 
     panic("Unknown argument") 
    } 
    } 

    return fmt.Sprintf("%s%d", a, b) 
} 
+9

Was für ein Schmerz. Ich wünschte, es wäre: 'func Concat1 (eine Zeichenkette = 'foo', b int = 10) Zeichenkette {' wie in den meisten anderen modernen Sprachen ... Es würde jedes der gegebenen Beispiele ziemlich auf eine Codezeile reduzieren. – Rotareti

+0

Haben wir eine Option, zwei verschiedene Funktionen zu schreiben und es dem Anrufer zu überlassen, explizit zu erklären, was sie erwarten. – ProgramCpp

1

Nein, es gibt keine Möglichkeit, Standardwerte angeben. Ich glaube, dies geschieht absichtlich, um die Lesbarkeit zu verbessern, auf Kosten von etwas mehr Zeit (und, hoffentlich, Gedanken) am Ende des Autors.

Ich denke, der richtige Ansatz, um einen "Standard" zu haben ist, eine neue Funktion zu haben, die diesen Standard der allgemeineren Funktion liefert. Dadurch wird Ihr Code klarer in Bezug auf Ihre Absicht. Zum Beispiel:

Mit sehr wenig Aufwand habe ich eine Funktion, die eine gemeinsame Sache macht und die generische Funktion wiederverwendet. Sie können dies in vielen Bibliotheken sehen, fmt.Println zum Beispiel fügt einfach eine neue Zeile zu dem, was fmt.Print sonst tun würde. Beim Lesen von jemandes Code ist es jedoch klar, was sie mit der aufgerufenen Funktion machen wollen. Mit Standardwerten weiß ich nicht, was passieren soll, ohne auch auf die Funktion zu verweisen, um zu referenzieren, was der Standardwert tatsächlich ist.