776 Stimmen

Optionale Parameter in Go?

Kann Go optionale Parameter haben? Oder kann ich einfach zwei Funktionen mit demselben Namen und einer unterschiedlichen Anzahl von Argumenten definieren?

1 Stimmen

In diesem Zusammenhang: So kann man obligatorische Parameter erzwingen, wenn man variadic als optionale Parameter verwendet: Ist es möglich, Kompilierzeit Fehler mit benutzerdefinierten Bibliothek in Golang auslösen?

95 Stimmen

Google hat eine schreckliche Entscheidung getroffen, denn manchmal hat eine Funktion einen 90%igen Anwendungsfall und dann einen 10%igen Anwendungsfall. Das optionale Argument ist für diese 10 % des Anwendungsfalls gedacht. Vernünftige Standardwerte bedeuten weniger Code, weniger Code bedeutet mehr Wartbarkeit.

6 Stimmen

Ich halte den Verzicht auf optionale Parameter für eine gute Entscheidung. Ich habe gesehen, dass optionale Parameter in C++ ziemlich stark missbraucht wurden - 40+ Argumente. Es ist sehr fehleranfällig, die Argumente durchzuzählen und sicherzustellen, dass man das richtige angibt, besonders ohne benannte Parameter. Viel besser ist es, eine Struktur zu verwenden, wie von @deamon erwähnt.

11voto

Alex Martelli Punkte 805329

Nein - weder noch. Gemäß der Go für C++-Programmierer docs,

Go unterstützt die Funktion nicht Überladen von Funktionen und unterstützt keine benutzer definierte Operatoren.

Ich kann keine ebenso klare Aussage finden, dass optionale Parameter nicht unterstützt werden, aber sie werden auch nicht unterstützt.

9 Stimmen

"Es gibt derzeit keinen Plan für diese [optionalen Parameter]". Ian Lance Taylor, Go-Sprachteam. groups.google.com/group/golang-nuts/msg/030e63e7e681fd3e

1 Stimmen

Das Fehlen von benutzerdefinierten Operatoren ist eine schreckliche Entscheidung, denn sie sind der Kern jeder ausgefeilten mathematischen Bibliothek, wie z. B. Punkt- oder Kreuzprodukte für die lineare Algebra, die häufig in 3D-Grafiken verwendet werden.

9voto

Maxs728 Punkte 551

Ich habe das Gefühl, dass ich viel zu spät zu dieser Party komme, aber ich war auf der Suche, um zu sehen, ob es einen besseren Weg gibt, dies zu tun als das, was ich bereits tue. Diese Art löst, was Sie versuchen zu tun, während auch das Konzept der ein optionales Argument geben.

package main

import "fmt"

type FooOpts struct {
    // optional arguments
    Value string
}

func NewFoo(mandatory string) {
    NewFooWithOpts(mandatory, &FooOpts{})
}

func NewFooWithOpts(mandatory string, opts *FooOpts) {
    if (&opts) != nil {
        fmt.Println("Hello " + opts.Value)
    } else {
        fmt.Println("Hello")
    }
}

func main() {
    NewFoo("make it work please")

    NewFooWithOpts("Make it work please", &FooOpts{Value: " World"})
}

Aktualisierung 1:

Ein funktionales Beispiel hinzugefügt, um die Funktionalität im Vergleich zum Beispiel zu zeigen

2 Stimmen

Das ist mir lieber als die anderen Alternativen. Auch dies ist ein Muster, das ich in vielen Bibliotheken gesehen habe. Wenn etwas verschiedene Optionen hat und wiederverwendbar sein soll, können Sie eine Struktur erstellen, um diese Optionen darzustellen und die Optionen als Parameter zu übergeben, oder Sie können nil die Optionen zur Verwendung von Standardwerten. Auch die Optionen können in einer eigenen Struktur dokumentiert werden und Sie können vordefinierte Optionssätze erstellen. Ich habe dies unter anderem in der GitHub-Client-Bibliothek und der Go-Cache-Bibliothek gesehen.

1 Stimmen

@madzohan bitte ändern Sie mein Code-Beispiel nicht, um es an Ihre Bedürfnisse anzupassen... Sie können verlangen, dass die Änderungen vorgenommen werden oder Ihr eigenes Beispiel unten bereitstellen... Ihr Beispiel hat die Funktionalität meines Beispiels grundlegend verändert. Eine ungültige Funktion, die etwas tut, braucht keine Rückgabe, um Ihren Bedürfnissen zu entsprechen.

7voto

Sumer Punkte 2192

Go unterstützt nicht optionale Parameter , Standardwerte et Funktionsüberladung aber Sie können einige Tricks anwenden, um das Gleiche zu erreichen.

Teilen Sie ein Beispiel, wo Sie unterschiedliche Anzahl und Typ von Argumenten in einer Funktion haben können. Es ist ein einfacher Code für einfaches Verständnis, den Sie um Fehlerbehandlung und etwas Logik ergänzen müssen.

func student(StudentDetails ...interface{}) (name string, age int, area string) {
    age = 10 //Here Age and area are optional params set to default values
    area = "HillView Singapore"

    for index, val := range StudentDetails {
        switch index {
            case 0: //the first mandatory param
                name, _ = val.(string)
            case 1: // age is optional param
                age, _ = val.(int)
            case 2: //area is optional param
                area, _ = val.(string)
        }
    }
    return
}

func main() {
    fmt.Println(student("Aayansh"))
    fmt.Println(student("Aayansh", 11))
    fmt.Println(student("Aayansh", 15, "Bukit Gombak, Singapore"))
}

14 Stimmen

Igitt, das ist ja furchtbar.

6voto

Malte Punkte 433

Sie können Zeiger verwenden und sie auf Null setzen, wenn Sie sie nicht verwenden wollen:

func getPosts(limit *int) {
  if optParam != nil {
    // fetch posts with limit 
  } else {
    // fetch all posts
  }
}

func main() {
  // get Posts, limit by 2
  limit := 2
  getPosts(&limit)

  // get all posts
  getPosts(nil)
}

2 Stimmen

Manchmal kann es viel einfacher sein, null als Parameter anzugeben, als zusätzliche Änderungen vorzunehmen.

0 Stimmen

Ich wollte sehen, ob optionale Parameter oder alternativ Parameter-Standardwerte möglich sind, damit dies möglich ist; func (n *Note) save(extension string = ".txt") { ... } macht ".txt" zur Standard-Erweiterung einer Datei, die jedoch geändert werden kann. Aber jetzt habe ich den Eindruck, dass dies nicht die Philosophie von go ist und man einfach separate Save() und SaveWithExtension(ext string) Funktionen verwenden sollte. Es ist besser, sich nicht dagegen zu wehren, denn das wird auf lange Sicht alles nur noch schwieriger machen.

0 Stimmen

Bis Sie anfangen, die iota und "auto incremented" Konstanten, in diesem Fall viel Glück mit nicht adressierbaren Konstanten (denn natürlich sind Konstanten magisch und haben keine Speicheradresse)

5voto

Clay Risser Punkte 2821

Sie können dies sehr schön in einer func kapseln, ähnlich wie unten.

package main

import (
        "bufio"
        "fmt"
        "os"
)

func main() {
        fmt.Println(prompt())
}

func prompt(params ...string) string {
        prompt := ": "
        if len(params) > 0 {
                prompt = params[0]
        }
        reader := bufio.NewReader(os.Stdin)
        fmt.Print(prompt)
        text, _ := reader.ReadString('\n')
        return text
}

In diesem Beispiel hat die Eingabeaufforderung standardmäßig einen Doppelpunkt und ein Leerzeichen vorangestellt .

: 

. . Sie können dies jedoch außer Kraft setzen, indem Sie der Prompt-Funktion einen Parameter übergeben.

prompt("Input here -> ")

Dies führt zu einer Eingabeaufforderung wie unten.

Input here ->

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X