Paramètre facultatif par défaut dans la fonction Swift

107

Lorsque je définirai la firstThingvaleur par défaut, nilcela fonctionnera, sans la valeur par défaut de, nilj'obtiens une erreur indiquant qu'il y a un paramètre manquant lors de l'appel de la fonction.

En tapant, Int?je pensais que cela le rendait facultatif avec une valeur par défaut de nil, ai-je raison? Et si oui, pourquoi ne fonctionne-t-il pas sans le = nil?

func test(firstThing: Int? = nil) {
    if firstThing != nil {
        print(firstThing!)
    }
    print("done")
}
test()
RickBrunstedt
la source
1
Considérez que vous pouvez écrire func test(firstThing: Int = 4): un non- Optionalparamètre avec une valeur par défaut. Le Optionaltype (qui est ce ?à quoi un nom de type se développe) est un type valeur; "paramètre facultatif" est un nom malheureux pour un paramètre qui peut ou non être présent lors d'un appel de fonction, quel que soit son type.
zneak
Quelle version de Swift utilisez-vous pour tester ce code? Votre code fonctionne bien !! Les options facultatives ne sont qu'un type, et les paramètres par défaut fonctionnent très bien comme avec un autre type dans Swift
Victor Sigler

Réponses:

210

Les options et les paramètres par défaut sont deux choses différentes.

Un facultatif est une variable qui peut être nil, c'est tout.

Les paramètres par défaut utilisent une valeur par défaut lorsque vous omettez ce paramètre, cette valeur par défaut est spécifiée comme ceci:func test(param: Int = 0)

Si vous spécifiez un paramètre facultatif, vous devez le fournir, même si la valeur que vous souhaitez transmettre est nil. Si votre fonction ressemble à ceci func test(param: Int?), vous ne pouvez pas l'appeler ainsi test(). Même si le paramètre est facultatif, il n'a pas de valeur par défaut.

Vous pouvez également combiner les deux et un paramètre qui prend une option où nilest la valeur par défaut, comme ceci: func test(param: Int? = nil).

EmilioPelaez
la source
27
"Si vous spécifiez un paramètre facultatif, vous devez le fournir". Super, merci Swift
andrewtweber
8
@andrewtweber Votre humour est apprécié, mais pour les débutants, j'ai pensé qu'il pourrait être utile de préciser que «facultatif» se réfère à la fourniture d'un objet ou d'une valeur. Vous n'êtes pas obligé de faire cela, vous pouvez fournir nil (qui représente l'absence d'objet ou de valeur) à la place. Vous n'avez qu'à décider quelle option vous choisissez.
JD Sandifer
23

L'argument par défaut vous permet d'appeler la fonction sans passer d'argument. Si vous ne passez pas l'argument, alors l'argument par défaut est fourni. Donc, en utilisant votre code, ceci ...

test()

... est exactement la même chose:

test(nil)

Si vous omettez l'argument par défaut comme celui-ci ...

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

... alors vous ne pouvez plus faire cela ...

test()

Si vous le faites, vous obtiendrez l'erreur "argument manquant" que vous avez décrite. Vous devez passer un argument à chaque fois, même si cet argument est juste nil:

test(nil)   // this works
Aaron Rasmussen
la source
18

Swift n'est pas comme les langages comme JavaScript, où vous pouvez appeler une fonction sans passer les paramètres et elle sera toujours appelée. Donc, pour appeler une fonction dans Swift, vous devez attribuer une valeur à ses paramètres.

Les valeurs par défaut des paramètres vous permettent d'attribuer une valeur sans la spécifier lors de l'appel de la fonction. C'est pourquoi test()fonctionne lorsque vous spécifiez une valeur par défaut sur la déclaration du test.

Si vous ne pas inclure cette valeur par défaut, vous devez fournir la valeur de l'appel: test(nil).

De plus, et pas directement lié à cette question, mais il vaut probablement la peine de le noter, vous utilisez la manière "C ++" de traiter des pointeurs éventuellement nuls, pour traiter d'éventuelles options nil dans Swift. Le code suivant est plus sûr (spécialement dans les logiciels multithreading), et il vous permet d'éviter le déballage forcé de l'option:

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

Vous confondez Optionalavec une valeur par défaut. An Optionalaccepte une valeur ou une valeur nulle. Avoir une valeur par défaut permet à l'argument d'être omis lors de l'appel de la fonction. Un argument peut avoir une valeur par défaut avec ou sans être de Optionaltype.

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

    print("param2 = \(param2)")

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

Exemple d'appels avec sortie:

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

Résumer:

  • Tapez avec? (par exemple, String?) est un Optionalpeut être nul ou peut contenir une instance de Type
  • L'argument avec la valeur par défaut peut être omis d'un appel à une fonction et la valeur par défaut sera utilisée
  • Si les deux Optionalet a la valeur par défaut, alors il peut être omis de l'appel de fonction OU peut être inclus et peut être fourni avec une valeur nil (par exemple param1: nil)
Chuck Krutsinger
la source
puis-je ajouter un paramètre par défaut en tant que variable comme let ou var? Merci
Yogesh Patel
@YogeshPatel Je ne sais pas ce que vous voulez dire.
Chuck Krutsinger
comme var myName = "Yogesh". Maintenant, ma fonction est comme 1. func getFilterNames (name: string = myName) {} cette approche ne fonctionne pas pour moi. 2. func getFilterNames (name: string = "Yogesh") {} cette approche fonctionne pour moi. Mais je veux le premier alors pouvez-vous s'il vous plaît m'aider à y parvenir. Merci beaucoup!
Yogesh Patel
@YogeshPatel Je pense que ce que vous voudrez peut-être, c'est func getFilterNames(name: inout String){ }ce qui vous permettra de modifier le nom qui a été transmis.
Chuck Krutsinger
Non non monsieur. je ne veux pas modifier mon paramètre. je veux juste donner la valeur par défaut à mon paramètre mais pas comme "Yogesh" statique. Je veux faire comme let name = "Yogesh" func dynamique getFilterNames (name: string = name) comme ça. obtenir ce monsieur? Merci!
Yogesh Patel
4

au cas où vous auriez besoin d'utiliser un paramètre booléen, il vous suffit d'attribuer la valeur par défaut.

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

alors vous pouvez utiliser sans ou avec le paramètre:

test() //here flag automatically has the default value: false
test(WithFlag: true) //here flag has the value: true
Niib Fouda
la source
Pour les personnes qui déconseillent cela, vous pouvez corriger la mauvaise chose à la place, afin que les autres comprennent.
Niib Fouda
3

«Paramètre facultatif» signifie «le type de ce paramètre est facultatif». Cela ne signifie pas "Ce paramètre est facultatif et peut donc être ignoré lorsque vous appelez la fonction".

Le terme «paramètre facultatif» semble prêter à confusion. Pour clarifier, il est plus précis de dire "paramètre de type facultatif" au lieu de "paramètre facultatif" car le mot "facultatif" ici n'est destiné qu'à décrire le type de valeur de paramètre et rien d'autre.

Todanley
la source
0

Si vous voulez pouvoir appeler le funcavec ou sans le paramètre, vous pouvez créer une seconde funcdu même nom qui appelle l'autre.

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

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

vous pouvez maintenant appeler une fonction nommée testsans ou sans paramètre.

// both work
test()
test(firstThing: 5)
Sean256
la source
Pourquoi définiriez-vous une fonction supplémentaire alors que vous pourriez simplement spécifier nil comme valeur par défaut pour le paramètre?
Peter Schorn
-1

C'est peu compliqué lorsque vous essayez de combiner un paramètre facultatif et une valeur par défaut pour ce paramètre. Comme ça,

func test(param: Int? = nil)

Ces deux idées sont complètement opposées. Lorsque vous avez un paramètre de type facultatif mais que vous lui fournissez également une valeur par défaut, ce n'est plus un type facultatif maintenant car il a une valeur par défaut. Même si la valeur par défaut est nulle, swift supprime simplement la liaison facultative sans vérifier la valeur par défaut.

Il est donc toujours préférable de ne pas utiliser nil comme valeur par défaut.

Shubham Naik
la source
1
Ceci est une erreur. Il n'y a rien de mal avec un optionnel ayant une valeur par défaut (même nil).
Brian Kendig
ce que je dis, c'est qu'une fois qu'une variable a une valeur par défaut, ce n'est pas une option dans le sens où elle aura toujours une valeur.
Shubham Naik
1
Ce n'est pas vrai et je ne suis pas sûr de ce que vous essayez de décrire. Je pense que vous dites à juste titre qu'une fois qu'une variable a une valeur qui lui est assignée, elle sera toujours assignée; vous ne pouvez pas l'annuler (et vous ne voudriez pas) à moins que vous ne le désallouiez. Et Swift vous donnera une erreur de compilation si vous essayez d'utiliser une variable avant qu'elle n'ait une valeur (comme dans var foo: String; print(foo)). Mais un argument de fonction avec une valeur par défaut est un argument optionnel (vous n'avez pas à le passer dans l'appel de fonction) et il peut aussi être de type facultatif (permettant nilde lui être assigné, même comme valeur par défaut).
Brian Kendig
Un facultatif est essentiellement un type d'union de <Type | Nil>, c'est-à-dire qu'il peut avoir le type spécifié ou le type nul. (En supposant que Swift ait des syndicats, ce qui n'est pas le cas, mais nous parlons conceptuellement ici). donc Int? = nul est parfaitement bien.
Shayne
-1

La valeur par défaut ne signifie pas la valeur par défaut du type de données. Ici, la valeur par défaut signifie la valeur définie au moment de la définition de la fonction. nous devons déclarer la valeur par défaut de la variable tout en définissant la variable dans la fonction.

Mahesh Kulkarni
la source