Standardmäßiger optionaler Parameter in der Swift-Funktion

107

Wenn ich firstThingden Standardwert nileinstelle, funktioniert dies, ohne den Standardwert von. nilIch erhalte die Fehlermeldung, dass beim Aufrufen der Funktion ein Parameter fehlt.

Durch die Eingabe Int?dachte ich, es wäre optional mit einem Standardwert von nil, habe ich Recht? Und wenn ja, warum funktioniert es nicht ohne das = nil?

func test(firstThing: Int? = nil) {
    if firstThing != nil {
        print(firstThing!)
    }
    print("done")
}
test()
RickBrunstedt
quelle
1
Beachten Sie, dass Sie schreiben können func test(firstThing: Int = 4): einen Nicht- OptionalParameter mit einem Standardwert. Der OptionalTyp (zu dem ?ein Typname erweitert wird) ist ein Werttyp. "optionaler Parameter" ist ein unglücklicher Name für einen Parameter, der bei einem Funktionsaufruf unabhängig von seinem Typ vorhanden sein kann oder nicht.
Zneak
Mit welcher Version von Swift haben Sie diesen Code getestet? Ihr Code funktioniert gut !! Optional ist nur ein Typ, und Standardparameter funktionieren einwandfrei wie bei einem anderen Typ in Swift
Victor Sigler

Antworten:

209

Optionale und Standardparameter sind zwei verschiedene Dinge.

Ein Optional ist eine Variable, die sein kann nil, das ist es.

Standardparameter verwenden einen Standardwert , wenn Sie diesen Parameter weglassen. Dieser Standardwert wird wie folgt angegeben:func test(param: Int = 0)

Wenn Sie einen optionalen Parameter angeben, müssen Sie ihn angeben, auch wenn der zu übergebende Wert lautet nil. Wenn Ihre Funktion so aussieht func test(param: Int?), können Sie sie nicht so aufrufen test(). Obwohl der Parameter optional ist, hat er keinen Standardwert.

Sie können die beiden auch kombinieren und einen Parameter verwenden, der optional nilist, wobei der Standardwert wie folgt lautet : func test(param: Int? = nil).

EmilioPelaez
quelle
27
"Wenn Sie einen optionalen Parameter angeben, müssen Sie ihn angeben". Großartig, danke Swift
andrewtweber
8
@andrewtweber Ihr Humor wird geschätzt, aber für Neulinge hielt ich es für hilfreich zu klären, dass "Optional" sich auf die Bereitstellung eines Objekts oder Werts bezieht. Sie müssen dies nicht tun, sondern können stattdessen nil (was das Fehlen eines Objekts oder Werts darstellt) angeben. Sie müssen sich nur entscheiden, welche Option Sie wählen.
JD Sandifer
23

Mit dem Standardargument können Sie die Funktion aufrufen, ohne ein Argument zu übergeben. Wenn Sie das Argument nicht übergeben, wird das Standardargument angegeben. Verwenden Sie also Ihren Code, um ...

test()

... ist genau das gleiche wie das:

test(nil)

Wenn Sie das Standardargument wie folgt weglassen ...

func test(firstThing: Int?) {
    if firstThing != nil {
        print(firstThing!)
    }
    print("done")
}

... dann kannst du das nicht mehr machen ...

test()

Wenn Sie dies tun, erhalten Sie den von Ihnen beschriebenen Fehler "fehlendes Argument". Sie müssen jedes Mal ein Argument übergeben, auch wenn dieses Argument nur nil:

test(nil)   // this works
Aaron Rasmussen
quelle
18

Swift ist nicht wie Sprachen wie JavaScript, in denen Sie eine Funktion aufrufen können, ohne die Parameter zu übergeben, und sie wird weiterhin aufgerufen. Um eine Funktion in Swift aufzurufen, benötigen Sie einen Wert seine Parameter zuzuweisen.

Mit Standardwerten für Parameter können Sie einen Wert zuweisen, ohne ihn beim Aufrufen der Funktion anzugeben. Deshalbtest() funktioniert, wenn Sie in der Testdeklaration einen Standardwert angeben.

Wenn Sie diesen Standardwert nicht angeben, müssen Sie den Wert für den Aufruf angeben: test(nil) .

Außerdem und nicht direkt mit dieser Frage verbunden, aber wahrscheinlich erwähnenswert, verwenden Sie die "C ++" - Methode, um mit möglicherweise Nullzeigern umzugehen, um mit möglichen Nulloptionen in Swift umzugehen. Der folgende Code ist sicherer (insbesondere in Multithreading-Software) und ermöglicht es Ihnen, das erzwungene Auspacken des optionalen Codes zu vermeiden:

func test(firstThing: Int? = nil) {
    if let firstThing = firstThing {
        print(firstThing)
    }
    print("done")
}
test()
nbloqs
quelle
7

Sie stehen im Konflikt Optionalmit einer Standardeinstellung. An Optionalakzeptiert entweder einen Wert oder Null. Mit einem Standardwert kann das Argument beim Aufrufen der Funktion weggelassen werden. Ein Argument kann einen Standardwert mit oder ohne OptionalTyp haben.

func someFunc(param1: String?,
          param2: String = "default value",
          param3: String? = "also has default value") {
    print("param1 = \(param1)")

    print("param2 = \(param2)")

    print("param3 = \(param3)")
}

Beispielaufrufe mit Ausgabe:

someFunc(param1: nil, param2: "specific value", param3: "also specific value")

param1 = nil
param2 = specific value
param3 = Optional("also specific value")

someFunc(param1: "has a value")

param1 = Optional("has a value")
param2 = default value
param3 = Optional("also has default value")

someFunc(param1: nil, param3: nil)

param1 = nil
param2 = default value
param3 = nil

Zusammenfassen:

  • Tippen Sie mit? (zB String?) ist eine OptionalNull oder kann eine Instanz vom Typ enthalten
  • Argumente mit Standardwert können in einem Funktionsaufruf weggelassen werden, und der Standardwert wird verwendet
  • Wenn beides Optionalund die Standardeinstellung hat, kann es im Funktionsaufruf weggelassen werden ODER es kann enthalten sein und mit einem Nullwert versehen werden (z. B. param1: nil).
Chuck Krutsinger
quelle
Kann ich einen Standardparameter als Variable wie let oder var hinzufügen? Danke
Yogesh Patel
@YogeshPatel Nicht sicher, was du meinst.
Chuck Krutsinger
wie var myName = "Yogesh". Jetzt ist meine Funktion wie 1. func getFilterNames (name: string = myName) {} Dieser Ansatz funktioniert bei mir nicht. 2. func getFilterNames (name: string = "Yogesh") {} Dieser Ansatz funktioniert für mich. Aber ich möchte den ersten, also können Sie mir bitte helfen, dies zu erreichen. Vielen Dank!
Yogesh Patel
@YogeshPatel Ich denke, was Sie vielleicht wollen, ist func getFilterNames(name: inout String){ }, dass Sie den Namen ändern können, der übergeben wurde.
Chuck Krutsinger
Nein, nein, Sir. Ich möchte meinen Parameter nicht ändern. Ich möchte meinem Parameter nur einen Standardwert geben, aber nicht wie statisches "Yogesh". Ich möchte wie let name = "Yogesh" dynamische Funktion getFilterNames (name: string = name) so machen. diesen Sir bekommen? Vielen Dank!
Yogesh Patel
3

"Optionaler Parameter" bedeutet "Typ dieses Parameters ist optional". Dies bedeutet nicht "Dieser Parameter ist optional und kann daher beim Aufrufen der Funktion ignoriert werden".

Der Begriff "optionaler Parameter" scheint verwirrend zu sein. Zur Verdeutlichung ist es genauer, "optionaler Typparameter" anstelle von "optionalem Parameter" zu sagen, da das Wort "optional" hier nur den Typ des Parameterwerts und nichts anderes beschreiben soll.

Todanley
quelle
3

Wenn Sie einen Bool-Parameter verwenden müssen, müssen Sie nur den Standardwert zuweisen.

func test(WithFlag flag: Bool = false){.....}

dann können Sie ohne oder mit dem Parameter verwenden:

test() //here flag automatically has the default value: false
test(WithFlag: true) //here flag has the value: true
Niib Fouda
quelle
Für Leute, die dies ablehnen, können Sie stattdessen das Falsche beheben, damit andere verstehen.
Niib Fouda
0

Wenn Sie den funcmit oder ohne Parameter aufrufen möchten, können Sie eine Sekunde funcmit demselben Namen erstellen, die den anderen aufruft.

func test(firstThing: Int?) {
    if firstThing != nil {
        print(firstThing!)
    }
    print("done")
}

func test() {
    test(firstThing: nil)
}

Jetzt können Sie eine Funktion mit testoder ohne Parameter aufrufen .

// both work
test()
test(firstThing: 5)
Sean256
quelle
Warum würden Sie eine zusätzliche Funktion definieren, wenn Sie nur nil als Standardwert für den Parameter angeben könnten?
Peter Schorn
-1

Es ist wenig schwierig, wenn Sie versuchen, optionale Parameter und Standardwerte für diesen Parameter zu kombinieren. So was,

func test(param: Int? = nil)

Diese beiden sind völlig gegensätzliche Vorstellungen. Wenn Sie einen optionalen Typparameter haben, diesen aber auch als Standardwert angeben, ist dieser jetzt kein optionaler Typ mehr, da er einen Standardwert hat. Selbst wenn der Standardwert Null ist, entfernt swift einfach die optionale Bindung, ohne den Standardwert zu überprüfen.

Es ist also immer besser, nil nicht als Standardwert zu verwenden.

Shubham Naik
quelle
1
Das ist falsch. Es ist nichts Falsches daran, dass eine Option einen Standardwert (gerade nil) hat.
Brian Kendig
Ich sage, sobald eine Variable einen Standardwert hat, ist sie nicht optional in dem Sinne, dass sie immer einen Wert hat.
Shubham Naik
1
Das stimmt nicht und ich bin mir nicht sicher, was Sie beschreiben wollen. Ich denke, Sie sagen zu Recht, dass einer Variablen immer ein Wert zugewiesen wird, sobald sie zugewiesen wurde. Sie können die Zuordnung nicht aufheben (und möchten es auch nicht), es sei denn, Sie geben die Zuordnung auf. Und Swift gibt Ihnen einen Kompilierungsfehler, wenn Sie versuchen, eine Variable zu verwenden, bevor sie einen Wert hat (wie in var foo: String; print(foo)). Ein Funktionsargument mit einem Standardwert ist jedoch ein optionales Argument (Sie müssen es nicht im Funktionsaufruf übergeben) und kann auch vom optionalen Typ sein (der nilauch als Standardwert zugewiesen werden kann).
Brian Kendig
Ein Optional ist im Wesentlichen ein Vereinigungstyp von <Typ | Nil>, dh es kann den angegebenen Typ oder den Nil-Typ haben. (Vorausgesetzt, Swift hatte Gewerkschaften, was nicht der Fall ist, aber wir sprechen hier konzeptionell). so Int? = Null ist vollkommen in Ordnung.
Shayne
-1

Standardwert bedeutet nicht Standardwert des Datentyps. Hier ist der Standardwert, der zum Zeitpunkt der Definition der Funktion definiert wurde. Wir müssen den Standardwert der Variablen deklarieren, während wir die Variable in der Funktion definieren.

Mahesh Kulkarni
quelle