Standardwert in der Go-Methode


99

Gibt es eine Möglichkeit, den Standardwert in der Go-Funktion anzugeben? Ich versuche dies in der Dokumentation zu finden, kann aber nichts finden, was darauf hinweist, dass dies überhaupt möglich ist.

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

Antworten:



117

NEIN, aber es gibt einige andere Optionen zum Implementieren des Standardwerts. Es gibt einige gute Blog-Beiträge zu diesem Thema, aber hier sind einige konkrete Beispiele.


** Option 1: ** Der Anrufer wählt 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: ** Ein einzelner optionaler Parameter am Ende
// 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: ** Eine Konfigurationsstruktur
// 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: ** Vollständige Analyse verschiedener variadischer Argumente (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)
}

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

Haben wir die Möglichkeit, zwei verschiedene Funktionen zu schreiben und es dem Anrufer zu überlassen, explizit zu sagen, was er erwartet?
ProgramCpp

@ProgramCpp Nein, Golang erlaubt keine Funktionsüberladung. Hat die Go-Sprache eine Funktions- / Methodenüberladung?
Vusal

9

Nein, es gibt keine Möglichkeit, Standardeinstellungen anzugeben. 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 für einen "Standard" besteht darin, eine neue Funktion zu haben, die diesen Standard für die allgemeinere Funktion bereitstellt. Wenn Sie dies tun, wird Ihr Code klarer in Bezug auf Ihre Absicht. Zum Beispiel:

func SaySomething(say string) {
    // All the complicated bits involved in saying something
}

func SayHello() {
    SaySomething("Hello")
}

Mit sehr wenig Aufwand habe ich eine Funktion erstellt, die eine gemeinsame Sache macht, und die generische Funktion wiederverwendet. Sie können dies in vielen Bibliotheken sehen, fmt.Printlnindem Sie beispielsweise nur eine neue Zeile zu dem hinzufügen, was fmt.Printsonst tun würde. Beim Lesen des Codes einer Person ist jedoch klar, was sie mit der von ihnen aufgerufenen Funktion vorhat. Bei Standardwerten weiß ich nicht, was passieren soll, ohne auch zur Funktion zu gehen, um auf den tatsächlichen Standardwert zu verweisen.


Ich mag und stimme dieser Antwort zu, aber verdammt noch mal, ich wünschte immer noch, sie hätten zumindest eine stumpfe, aber idiomatische Art, dies zu tun.
Sam Gomena

12
Das Argument "Nur eine weitere Funktion hinzufügen" kann zu einer Explosion von Methoden führen, die für den Umgang mit mehreren Permutationen erforderlich sind, erfordert die Entscheidung über aussagekräftige, erkennbare und einprägsame Namen für diese Methoden und erhöht die Belastung beim Erlernen der Pakete, die mehr Methoden verwenden als . weniger. #jmtcw
MikeSchinkel
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.