web-dev-qa-db-fra.com

Qu'est-ce qu'une valeur optionnelle dans Swift?

De Documentation Apple :

Vous pouvez utiliser if et let ensemble pour traiter les valeurs éventuellement manquantes. Ces valeurs sont représentées comme des optionnels. Une valeur facultative contient une valeur ou contient nil pour indiquer que la valeur est manquante. Ecrivez un point d'interrogation (?) après le type d'une valeur pour marquer la valeur comme facultative.

Pourquoi voudriez-vous utiliser une valeur optionnelle?

237
Tim Vermeulen

Prenons l'exemple de NSError. Si aucune erreur n'est renvoyée, vous souhaitez rendre facultatif le renvoi de Nil. Il n'y a aucun intérêt à lui attribuer une valeur s'il n'y a pas d'erreur.

var error: NSError? = nil

Cela vous permet également d'avoir une valeur par défaut. Donc, vous pouvez définir une méthode une valeur par défaut si la fonction n'est pas transmis quoi que ce soit

func doesntEnterNumber(x: Int? = 5) -> Bool {
    if (x == 5){
        return true
    } else {
        return false
    }
}
14
John Riselvato

Vous ne pouvez pas avoir une variable qui pointe sur nil dans Swift - il n'y a pas de pointeurs ni de pointeurs nuls. Mais dans une API, vous voulez souvent pouvoir indiquer soit un type de valeur spécifique, soit un manque de valeur - par exemple. ma fenêtre a-t-elle un délégué et, dans l'affirmative, qui est-ce? Les options sont un moyen sûr, pour la mémoire et le type de Swift.

12
rickster

J'ai fait une réponse courte, résumant l'essentiel de ce qui précède, pour éliminer l'incertitude qui me trottait dans la tête en tant que débutant:

Contrairement à Objective-C, aucune variable ne peut contenir nil dans Swift, le type de variable optionnelle a donc été ajouté (variables suffixées par "?"):

    var aString = nil //error

La grande différence est que les variables optionnelles ne stockent pas directement de valeurs (comme le feraient des variables Obj-C normales). Elles contiennent deux états : " a une valeur " ou " a la valeur nil ":

    var aString: String? = "Hello, World!"
    aString = nil //correct, now it contains the state "has nil"

Cela étant, vous pouvez vérifier ces variables dans différentes situations:

if let myString = aString? {
     println(myString)
}
else { 
     println("It's nil") // this will print in our case
}

En utilisant le "!" suffixe, vous pouvez également accéder aux valeurs qui y sont contenues, uniquement si elles existent . (c'est-à-dire que ce n'est pas nul ):

let aString: String? = "Hello, World!"
// var anotherString: String = aString //error
var anotherString: String = aString!

println(anotherString) //it will print "Hello, World!"

C'est pourquoi vous devez utiliser "?" et "!" et ne pas les utiliser tous par défaut. (ce fut ma plus grande confusion)

Je suis également d'accord avec la réponse ci-dessus: Le type facultatif ne peut pas être utilisé comme booléen.

11
Teodor Ciuraru

Dans l’objectif C, les variables sans valeur étaient égales à «nil» (il était également possible d’utiliser des valeurs «nil» identiques à 0 et false), il était donc possible d’utiliser des variables dans des instructions conditionnelles (les variables ayant les mêmes valeurs que «TRUE»). 'et ceux sans valeur étaient égaux à' FALSE ').

Swift assure la sécurité du type en fournissant une «valeur optionnelle». Cela évite les erreurs d’attribution de variables de types différents.

Ainsi, dans Swift, seuls des booléens peuvent être fournis sur des instructions conditionnelles.

var hw = "Hello World"

Ici, même si 'hw' est une chaîne, elle ne peut pas être utilisée dans une instruction if comme dans Objective C.

//This is an error

if hw

 {..}

Pour cela, il doit être créé comme,

var nhw : String? = "Hello World"

//This is correct

if nhw

 {..}
7
Gokul

La valeur facultative vous permet de montrer l'absence de valeur. Un peu comme NULL en SQL ou NSNull en Objective-C. Je suppose que ce sera une amélioration car vous pouvez l’utiliser même pour les types "primitifs".

// Reimplement the Swift standard library's optional type
enum OptionalValue<T> {
    case None
    case Some(T)
}
var possibleInteger: OptionalValue<Int> = .None
possibleInteger = .Some(100)”

Extrait de: Apple Inc. «Le langage de programmation Swift.» IBooks. https://itun.es/gb/jEUH0.l

5
Maria Zverina

Une option signifie que Swift n'est pas tout à fait sûr si la valeur correspond au type: par exemple, Int? signifie que Swift n'est pas tout à fait sûr si le nombre est un Int.

Pour le supprimer, vous pouvez utiliser trois méthodes.

1) Si vous êtes absolument sûr du type, vous pouvez utiliser un point d'exclamation pour le dérouler de la manière suivante:

// Here is an optional variable:

var age: Int?

// Here is how you would force unwrap it:

var unwrappedAge = age!

Si vous forcez de dérouler une option et qu'elle est égale à nil, vous risquez de rencontrer l'erreur suivante:

 enter image description here

Ce n'est pas forcément sûr, alors voici une méthode qui pourrait vous empêcher de planter si vous n'êtes pas sûr du type et de la valeur:

Les méthodes 2 et 3 protègent contre ce problème.

2) Le facultatif implicitement non emballé

 if let unwrappedAge = age {

 // continue in here

 }

Notez que le type non emballé est maintenant Int, plutôt que Int?.

3) La déclaration de garde

 guard let unwrappedAge = age else { 
   // continue in here
 }

À partir de là, vous pouvez continuer et utiliser la variable non enveloppée. Assurez-vous uniquement de forcer le déroulement (avec un!), Si vous êtes sûr du type de la variable.

Bonne chance pour votre projet!

3
GJZ

Quand j'ai commencé à apprendre Swift, il était très difficile de comprendre pourquoi optionnel .

Pensons de cette façon… .. Prenons une classe Person qui a deux propriétés name et company.

class Person: NSObject {

    var name : String //Person must have a value so its no marked as optional
    var companyName : String? ///Company is optional as a person can be unemployed that is nil value is possible

    init(name:String,company:String?) {

        self.name = name
        self.companyName = company

    }
}

Créons maintenant quelques objets de Person

var tom:Person = Person.init(name: "Tom", company: "Apple")//posible
var bob:Person = Person.init(name: "Bob", company:nil) // also Possible because company is marked as optional so we can give Nil

Mais nous ne pouvons pas passer de Nil à name

var personWithNoName:Person = Person.init(name: nil, company: nil)

Maintenant, parlons de la raison pour laquelle nous utilisons optional?. Considérons une situation dans laquelle nous voulons ajouter Inc après que le nom de la société comme Apple sera Apple Inc. Nous devons ajouter Inc après le nom de la société et en caractères d’impression.

print(tom.companyName+" Inc") ///Error saying optional is not unwrapped.
print(tom.companyName!+" Inc") ///Error Gone..we have forcefully unwrap it which is wrong approach..Will look in Next line
print(bob.companyName!+" Inc") ///Crash!!!because bob has no company and nil can be unwrapped.

Voyons maintenant pourquoi l’option est mise en place.

if let companyString:String = bob.companyName{///Compiler safely unwrap company if not nil.If nil,no unwrap.

    print(companyString+" Inc") //Will never executed and no crash!!!
}

Permet de remplacer bob par tom

if let companyString:String = tom.companyName{///Compiler safely unwrap company if not nil.If nil,no unwrap.

    print(companyString+" Inc") //Will never executed and no crash!!!
}

Et Félicitations! nous avons correctement traité optional?

Donc, les points de réalisation sont

  1. Nous marquerons une variable comme optionnelle s'il est possible d'être nil
  2. Si nous voulons utiliser cette variable quelque part dans le code, le compilateur vous rappellera que nous devons vérifier si nous avons traité correctement cette variable Si elle contient nil.

Merci ... Bonne codage

1

Permet d’expérimenter avec le code ci-dessous Aire de jeu .

var sampleString: String? ///Optional, Possible to be nil

sampleString = nil ////perfactly valid as its optional

sampleString = "some value"  //Will hold the value

if let value = sampleString{ /// the sampleString is placed into value with auto force upwraped.

    print(value+value)  ////Sample String merged into Two
}

sampleString = nil // value is nil and the

if let value = sampleString{

    print(value + value)  ///Will Not execute and safe for nil checking
}

//   print(sampleString! + sampleString!)  //this line Will crash as + operator can not add nil
0
Tunvir Rahman Tusher

De https://developer.Apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/OptionalChaining.html :

Le chaînage facultatif est un processus permettant d'interroger et d'appeler des propriétés, des méthodes et des indices sur une propriété facultative qui peut actuellement être nulle. Si facultatif contient une valeur, la propriété, la méthode ou l'appel en indice aboutit; si facultatif est nil, la propriété, la méthode ou l'appel en indice renvoie nil. Plusieurs requêtes peuvent être chaînées ensemble et toute la chaîne échoue normalement si l'un des liens est nul.

Pour mieux comprendre, lisez le lien ci-dessus.

0
nizama bunti

Bien...

? (Facultatif) indique que votre variable peut contenir une valeur nulle alors que ! (unfrapper) indique que votre variable doit avoir une mémoire (ou une valeur) lorsqu’elle est utilisée (essayée d’obtenir une valeur) au moment de l’exécution.

La principale différence réside dans le fait que l'enchaînement facultatif échoue normalement lorsque l'option est nul, alors que le déballage forcé déclenche une erreur d'exécution lorsque l'option est nul.

Pour refléter le fait que le chaînage facultatif peut être appelé avec une valeur nulle, le résultat d'un appel de chaînage facultatif est toujours une valeur facultative, même si la propriété, la méthode ou l'indice que vous interrogez renvoie une valeur non optionnelle. Vous pouvez utiliser cette valeur de retour facultative pour vérifier si l'appel de chaînage facultatif a abouti (la valeur renvoyée contient une valeur) ou a échoué en raison d'une valeur nulle dans la chaîne (la valeur facultative renvoyée est nil).

Plus précisément, le résultat d'un appel de chaînage facultatif est du même type que la valeur de retour attendue, mais encapsulé dans une valeur facultative. Une propriété qui retourne normalement un Int retournera un Int? Quand elle sera accédée via un chaînage optionnel.

var defaultNil : Int?  // declared variable with default nil value
println(defaultNil) >> nil  

var canBeNil : Int? = 4
println(canBeNil) >> optional(4)

canBeNil = nil
println(canBeNil) >> nil

println(canBeNil!) >> // Here nil optional variable is being unwrapped using ! mark (symbol), that will show runtime error. Because a nil optional is being tried to get value using unwrapper

var canNotBeNil : Int! = 4
print(canNotBeNil) >> 4

var cantBeNil : Int = 4
cantBeNil = nil // can't do this as it's not optional and show a compile time error

Voici le tutoriel de base en détail, par le Comité de développeurs Apple: Chaînage facultatif

0
Krunal

Une option dans Swift est un type pouvant contenir une valeur ou aucune valeur. Les options sont écrites en ajoutant un? à n'importe quel type:

var name: String?

Vous pouvez vous référer à ce lien pour approfondir vos connaissances: https://medium.com/@agoiabeladeyemi/optionals-in-Swift-2b141f12f870

0
Vicky Prajapati