Kann Go optionale Parameter haben? Oder kann ich einfach zwei Funktionen mit demselben Namen und einer unterschiedlichen Anzahl von Argumenten definieren?
Ist make
also ein Sonderfall? Oder ist sie gar nicht als Funktion implementiert
Kann Go optionale Parameter haben? Oder kann ich einfach zwei Funktionen mit demselben Namen und einer unterschiedlichen Anzahl von Argumenten definieren?
Go hat keine optionalen Parameter noch unterstützt es das Überladen von Methoden :
Der Methodenversand wird vereinfacht, wenn er nicht auch noch den Typabgleich durchführen muss muss. Erfahrung mit anderen Sprachen hat uns gezeigt, dass eine Vielzahl von Methoden mit demselben Namen aber unterschiedlichen Signaturen gelegentlich nützlich ist, aber in der Praxis auch in der Praxis verwirrend und anfällig sein kann. Nur nach dem Namen abgleichen und Konsistenz in den Typen war eine wichtige vereinfachende Entscheidung in Go's Typ System.
@Mk12 make
ist ein Sprachkonstrukt und die oben genannten Regeln gelten nicht. Siehe diese verwandte Frage .
Es wäre großartig, wenn Strukturen hier Standardwerte haben könnten; alles, was der Benutzer auslässt, wird standardmäßig auf den Nullwert für diesen Typ gesetzt, der ein geeignetes Standardargument für die Funktion sein kann oder auch nicht.
@lytnus, ich hasse es, Haare zu spalten, aber Felder, für die Werte weggelassen werden, würden standardmäßig den "Nullwert" für ihren Typ annehmen; nil ist ein anderes Tier. Sollte der Typ des ausgelassenen Feldes zufällig ein Zeiger sein, wäre der Nullwert nil.
@burfl ja, außer dass der Begriff "Nullwert" für int/float/string-Typen absolut nutzlos ist, weil diese Werte sinnvoll sind und man daher nicht unterscheiden kann, ob der Wert in der Struktur weggelassen wurde oder ob absichtlich ein Nullwert übergeben wurde.
Für eine beliebige, potentiell große Anzahl von optionalen Parametern ist es eine nette Redewendung, Folgendes zu verwenden Funktionelle Optionen .
Für Ihren Typ Foobar
schreiben Sie zunächst nur einen Konstruktor:
func NewFoobar(options ...func(*Foobar) error) (*Foobar, error){
fb := &Foobar{}
// ... (write initializations with default values)...
for _, op := range options{
err := op(fb)
if err != nil {
return nil, err
}
}
return fb, nil
}
wobei jede Option eine Funktion ist, die die Foobar verändert. Bieten Sie dann bequeme Möglichkeiten für den Benutzer, Standardoptionen zu verwenden oder zu erstellen, zum Beispiel :
func OptionReadonlyFlag(fb *Foobar) error {
fb.mutable = false
return nil
}
func OptionTemperature(t Celsius) func(*Foobar) error {
return func(fb *Foobar) error {
fb.temperature = t
return nil
}
}
Der Übersichtlichkeit halber können Sie dem Typ der Optionen einen Namen geben ( Spielplatz ) :
type OptionFoobar func(*Foobar) error
Wenn Sie obligatorische Parameter benötigen, fügen Sie diese als erste Argumente des Konstruktors vor der variadischen options
.
Die wichtigsten Vorteile des Funktionelle Optionen Idiom sind:
Diese Technik wurde geprägt von Rob Pike und auch demonstriert durch Dave Cheney .
Clever, aber zu kompliziert. Die Philosophie von Go ist es, Code auf unkomplizierte Weise zu schreiben. Übergeben Sie einfach eine Struktur und testen Sie auf Standardwerte.
Zu Ihrer Information: Der ursprüngliche Autor dieser Redewendung, zumindest der erste angegebene Herausgeber, ist Commander Rob Pike, den ich für die Go-Philosophie für maßgeblich genug halte. Link -. commandcenter.blogspot.bg/2014/01/ . Suchen Sie auch nach "Einfach ist kompliziert".
Weder optionale Parameter noch Funktionsüberladungen werden in Go unterstützt. Go unterstützt jedoch eine variable Anzahl von Parametern: Übergabe von Argumenten an ... Parameter
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.
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.
5 Stimmen
@Jonathan es gibt mehrere Möglichkeiten, damit umzugehen. Eine Möglichkeit ist, eine Struktur mit allen Parametern für die Funktion zu übergeben. Dies hat den zusätzlichen Vorteil, dass man benannte Parameter hat (klarer als Positionsparameter) und alle Parameter, die nicht übergeben werden, ihren Standardwert haben. Und natürlich kann man auch einfach eine Wrapper-Funktion erstellen, die den Standardwert an die vollständige Funktion übergibt. z.B. Query und QueryWithContext
2 Stimmen
@Falco moderne IDEs generieren automatisch benannte Parameter aus der Semantik, so dass es nicht ideal erscheint, den Programmierer zu zwingen, seinen Code umzugestalten, um etwas zu tun, was eine IDE für Sie tun kann
0 Stimmen
@Jonathan Die meisten IDEs zeigen beim beiläufigen Lesen von Code keine Parameternamen an. Normalerweise muss man den Funktionsaufruf auswählen, um die Signatur zu sehen, und dann die tatsächlichen Parameter der Liste der Parameternamen im Kopf zuordnen. Die meisten Codestile / Clean Code Papers raten auch von langen Parameterlisten in Funktionen ab. Man sollte entweder eine Struktur übergeben oder ein objektorientiertes Design verwenden, wenn man eine Funktion mit vielen Parametern hat.
1 Stimmen
@Falco Ich habe ausdrücklich erklärt modern IDEs. Die meisten Legacy-IDEs haben das von Ihnen erwähnte Verhalten.
2 Stimmen
@Jonathan es scheint nicht zu funktionieren out of the box in VS Code, Visual Studio, IntelliJ, Atom oder Sublime. Auf welche IDE beziehen Sie sich, oder gibt es Erweiterungen/Einstellungen, die dies ermöglichen?