Parametro opzionale predefinito nella funzione Swift


107

Quando si imposta firstThingcome predefinito nilquesto funzionerà, senza il valore predefinito di nilottengo un errore che non è presente un parametro quando si chiama la funzione.

Digitando Int?ho pensato che lo rendesse opzionale con un valore predefinito di nil, ho ragione? E se è così, perché non funziona senza = nil?

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

1
Considera che puoi scrivere func test(firstThing: Int = 4): un non Optionalparametro con un valore predefinito. Il Optionaltipo (che è ciò ?a cui si espande in un nome di tipo) è un tipo di valore; "parametro opzionale" è un nome sfortunato per un parametro che può o meno essere presente in una chiamata di funzione, indipendentemente dal suo tipo.
zneak

Quale versione di Swift hai utilizzato per testare questo codice? Il tuo codice funziona bene !! Gli opzionali sono solo un tipo e i parametri predefiniti funzionano bene come con un altro tipo in Swift
Victor Sigler

Risposte:


210

Optionals e parametri di default sono due cose diverse.

Un Opzionale è una variabile che può essere nil, questo è tutto.

I parametri predefiniti utilizzano un valore predefinito quando si omette quel parametro, questo valore predefinito è specificato in questo modo:func test(param: Int = 0)

Se si specifica un parametro facoltativo, è necessario fornirlo, anche se il valore che si desidera passare è nil. Se la tua funzione ha questo aspetto func test(param: Int?), non puoi chiamarla in questo modo test(). Anche se il parametro è facoltativo, non ha un valore predefinito.

È inoltre possibile combinare le due cose e avere un parametro che prende un optional in cui nilè il valore predefinito, in questo modo: func test(param: Int? = nil).


27
"Se si specifica un parametro facoltativo, è necessario fornirlo". Fantastico, grazie Swift
andrewtweber

8
@andrewtweber Il tuo umorismo è apprezzato, ma per i neofiti, ho pensato che potrebbe essere utile chiarire che "Opzionale" si riferisce alla fornitura di un oggetto o di un valore. Non devi farlo, puoi invece fornire nil (che rappresenta l'assenza di un oggetto o di un valore). Devi solo decidere quale opzione stai scegliendo.
JD Sandifer

23

L'argomento predefinito consente di chiamare la funzione senza passare un argomento. Se non si passa l'argomento, viene fornito l'argomento predefinito. Quindi usando il tuo codice, questo ...

test()

... è esattamente lo stesso di questo:

test(nil)

Se tralascia l'argomento predefinito come questo ...

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

... allora non puoi più farlo ...

test()

Se lo fai, otterrai l'errore "argomento mancante" che hai descritto. Devi passare un argomento ogni volta, anche se quell'argomento è solo nil:

test(nil)   // this works

18

Swift non è come i linguaggi come JavaScript, dove puoi chiamare una funzione senza passare i parametri e verrà comunque chiamata. Quindi, per chiamare una funzione in Swift, è necessario assegnare un valore ai suoi parametri.

I valori predefiniti per i parametri consentono di assegnare un valore senza specificarlo quando si chiama la funzione. Ecco perché test()funziona quando si specifica un valore predefinito nella dichiarazione del test.

Se non si include il valore di default, è necessario fornire il valore sulla chiamata: test(nil).

Inoltre, e non direttamente correlato a questa domanda, ma probabilmente vale la pena notare, stai usando il modo "C ++" di trattare con eventuali puntatori nulli, per trattare con possibili nulli optionals in Swift. Il codice seguente è più sicuro (specialmente nei software multithreading) e consente di evitare lo scartamento forzato dell'opzionale:

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

7

Stai confondendo Optionalcon avere un valore predefinito. An Optionalaccetta un valore o zero. La presenza di un valore predefinito consente di omettere l'argomento nella chiamata della funzione. Un argomento può avere un valore predefinito con o senza essere di Optionaltipo.

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

    print("param2 = \(param2)")

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

Chiamate di esempio con output:

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

Riassumere:

  • Digitare con? (es. String?) Optionalpuò essere nil o può contenere un'istanza di Type
  • L'argomento con il valore predefinito può essere omesso da una chiamata alla funzione e verrà utilizzato il valore predefinito
  • Se entrambi Optionale sono predefiniti, allora può essere omesso dalla chiamata di funzione OR può essere incluso e può essere fornito con un valore nil (ad esempio param1: nil)

posso aggiungere un parametro predefinito come variabile come let o var? Grazie
Yogesh Patel

@YogeshPatel Non sono sicuro di cosa intendi.
Chuck Krutsinger

come var myName = "Yogesh". Ora, la mia funzione è come 1. func getFilterNames (name: string = myName) {} questo approccio non funziona per me. 2. func getFilterNames (name: string = "Yogesh") {} questo approccio funziona per me. Ma voglio il primo, quindi puoi aiutarmi a raggiungere questo obiettivo. Molte grazie!
Yogesh Patel

@YogeshPatel Penso che quello che potresti desiderare è func getFilterNames(name: inout String){ }che ti permetta di modificare il nome che è stato passato.
Chuck Krutsinger

No no signore. non voglio modificare il mio parametro. voglio solo dare un valore predefinito al mio parametro ma non come "Yogesh" statico. voglio fare come let name = "Yogesh" funzione dinamica getFilterNames (name: string = name) come questo. ottenere questo signore? Grazie!
Yogesh Patel

4

nel caso in cui sia necessario utilizzare un parametro bool, è sufficiente assegnare il valore predefinito.

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

quindi puoi usare senza o con il parametro:

test() //here flag automatically has the default value: false
test(WithFlag: true) //here flag has the value: true

Per le persone che votano negativamente, puoi invece correggere la cosa sbagliata, così gli altri capiranno.
Niib Fouda

3

"Parametro opzionale" significa "il tipo di questo parametro è facoltativo". Non significa "Questo parametro è opzionale e, quindi, può essere ignorato quando si chiama la funzione".

Il termine "parametro opzionale" sembra creare confusione. Per chiarire, è più accurato dire "parametro di tipo opzionale" invece di "parametro opzionale" poiché la parola "opzionale" qui ha solo lo scopo di descrivere il tipo di valore del parametro e nient'altro.


0

Se vuoi poter chiamare il funccon o senza il parametro puoi creare un secondo funccon lo stesso nome che chiami l'altro.

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

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

ora puoi chiamare una funzione denominata testsenza o senza il parametro.

// both work
test()
test(firstThing: 5)

Perché dovresti definire una funzione aggiuntiva quando potresti semplicemente specificare nil come valore predefinito per il parametro?
Peter Schorn

-1

È un po 'complicato quando si tenta di combinare il parametro opzionale e il valore predefinito per quel parametro. Come questo,

func test(param: Int? = nil)

Queste due sono idee completamente opposte. Quando si dispone di un parametro di tipo facoltativo ma gli si fornisce anche un valore predefinito, ora non è più un tipo facoltativo poiché ha un valore predefinito. Anche se il valore predefinito è nullo, swift rimuove semplicemente l'associazione facoltativa senza verificare quale sia il valore predefinito.

Quindi è sempre meglio non utilizzare nil come valore predefinito.


1
Questo non è corretto. Non c'è niente di sbagliato nel fatto che un opzionale abbia un valore predefinito (pari nil).
Brian Kendig

quello che sto dicendo è che una volta che una variabile ha un valore predefinito, non è un opzionale nel senso che avrà sempre un valore.
Shubham Naik

1
Non è vero e non sono sicuro di cosa stai cercando di descrivere. Penso che tu stia dicendo correttamente che una volta che una variabile ha un valore assegnato ad essa, verrà sempre assegnato; non puoi annullarne l'assegnazione (né vorresti farlo) a meno che non lo rilasci. E Swift ti darà un errore di compilazione se provi a usare una variabile prima che abbia un valore (come in var foo: String; print(foo)). Ma un argomento di funzione con un valore predefinito è un argomento facoltativo (non è necessario passarlo nella chiamata di funzione) e può anche essere di tipo Opzionale (consentendo nildi assegnargli anche come valore predefinito).
Brian Kendig

Un Opzionale è essenzialmente un tipo di unione di <Tipo | Nil>, ovvero può avere il tipo specificato o il tipo Nil. (Supponendo che swift avesse unioni, cosa che non fa, ma qui stiamo parlando concettualmente). così Int? = zero va benissimo.
Shayne

-1

Il valore predefinito non indica il valore predefinito del tipo di dati. Qui il valore predefinito indica il valore medio definito al momento della definizione della funzione. dobbiamo dichiarare il valore di default della variabile mentre definiamo la variabile in funzione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.