114 votes

Comment résoudre "L'interpolation de chaîne produit une description de débogage pour une valeur facultative; vouliez-vous rendre cela explicite?" dans Xcode 8.3 beta?

Depuis la beta 8.3, zillions mises en garde "de la Chaîne d'interpolation produit une version de débogage de description pour une valeur facultative; avez-vous l'intention de faire de cette explicites?" est apparu dans mon code.

Par exemple, l'avertissement sauté dans la situation suivante, où les options pourraient conduire à néant:

let msg = "*** Error \(options["taskDescription"]): cannot load \(sUrl) \(error)"

Comme précédemment, il est ok pour moi (et le compilateur) les options pour être interpolé comme "nil". Mais le compilateur a changé son esprit.

Ce que le compilateur indique est d'ajouter une Chaîne de constructeur avec une description comme suit:

let msg = "*** Error \(String(describing: options["taskDescription"])): cannot load \(sUrl) \(error)"

Évidemment, le résultat est explicite, mais aussi très, très lourd à mon avis. Est-il une meilleure solution? Dois-je fixer tous ces avertissement ou mieux d'attendre pour la prochaine beta?

Screenshot for description

133voto

Hamish Points 42073

C'est un changement qui a été fait dans ce pull request en raison du fait que l'interpolation Optional(...) dans la chaîne résultante est souvent indésirable, et peut être d'autant plus surprenant dans le cas implicitement déballé options. Vous pouvez voir la description complète de ce changement sur la liste de diffusion ici.

Comme mentionné dans la demande d'extraction de discussion (bien que malheureusement pas par Xcode) – un peu plus agréable pour réduire au silence l'avertissement que l'utilisation de l' String(describing:) est à ajouter un cast vers le type facultatif de ce que vous êtes en interpolant, donc par exemple:

var i: Int? = 5
var d: Double? = nil

print("description of i: \(i as Int?)")    // description of i: Optional(5)
print("description of d: \(d as Double?)") // description of d: nil

Ce qui peut aussi être généralisés à l' as Optional:

print("description of i: \(i as Optional)") // description of i: Optional(5)
print("description of d: \(d as Optional)") // description of d: nil

Une autre voie possible pour réduire au silence l'avertissement est pour accéder Optionals' debugDescription:

print("description of i: \(i.debugDescription)") // description of i: Optional(5)
print("description of d: \(d.debugDescription)") // description of d: nil

Bien qu'il est important de noter que la documentation d' CustomDebugStringConvertible décourage l'accédant directement de l' debugDescription.

30voto

DustyFootDev Points 11

Deux des moyens plus faciles de faire face à ce problème.

Option 1:

La première serait de "force de déballage" la valeur que vous souhaitez retourner à l'aide d'un bang (!)

var someValue: Int? = 5
print(someValue!)

Sortie:

5

Option 2:

L'autre façon, qui pourrait être la meilleure façon est de "en toute sécurité-unwrap" la valeur que vous voulez retourner.

var someValue: Int? = 5

if let newValue = someValue {
    print(newValue)
}

Sortie:

5

Recommande d'aller avec l'option 2.

Conseil: Évitez de le forcer à déballer (!) si possible, comme nous ne savons pas si nous aurons toujours de la valeur à être déballé.

16voto

brian.clear Points 2424

semble utiliser String (décrivant: facultatif) est le plus simple.

valeur par défaut ?? n'a aucun sens pour les non-chaînes, par exemple, Int.
Si Int est égal à zéro, vous souhaitez que le journal indique "nil", pas par défaut pour un autre Int, par exemple 0.

Quelques codes de terrain de jeu à tester:

 var optionalString : String? = nil
var optionalInt : Int? = nil

var description_ = ""
description_ = description_ + "optionalString: \(String(describing: optionalString))\r"
description_ = description_ + "   optionalInt: \(String(describing: optionalInt))\r"

print(description_)
 

Sortie

 optionalString: nil
optionalInt: nil
 

14voto

anorskdev Points 1124

Après la mise à jour de Xcode 8.3 et reçoit beaucoup de messages d'avertissement, je suis venu avec la suivante qui est plus comme à l'origine le comportement de la sortie, simple d'ajouter, de réduire la verbosité désirée de l'utilisation d'une Chaîne de caractères(la description:)" à la fois dans le code et de sortie.

Fondamentalement, ajouter une extension Optionnelle qui donne une Chaîne de caractères décrivant la chose dans l'option, ou tout simplement "nil" s'il n'est pas. En outre, si la chose en l'option est une Chaîne de caractères, mettez-la entre guillemets.

extension Optional {
    var orNil : String {
        if self == nil {
            return "nil"
        }
        if "\(Wrapped.self)" == "String" {
            return "\"\(self!)\""
        }
        return "\(self!)"
    }
}

Et l'utilisation dans une aire de jeu:

var s : String?
var i : Int?
var d : Double?

var mixed = "s = \(s.orNil)    i = \(i.orNil)   d = \(d.orNil)" // "s = nil    i = nil   d = nil"

d = 3
i = 5
s = ""
mixed = "s = \(s.orNil)    i = \(i.orNil)   d = \(d.orNil)" // "s = ""    i = 5   d = 3.0"

s = "Test"
d = nil
mixed = "s = \(s.orNil)    i = \(i.orNil)   d = \(d.orNil)" // "s = "Test"    i = 5   d = nil"

Merci pour l'aide du lien suivant:

check-si-variable-est-une-option-et-ce-type-il-wraps

12voto

dar512 Points 475

Voir la solution de Ole Begeman pour cela . J'aime cela. Il crée un opérateur ??? que vous pouvez ensuite utiliser comme ceci:

 var someValue: Int? = 5
print("The value is \(someValue ??? "unknown")")
// → "The value is 5"
someValue = nil
print("The value is \(someValue ??? "unknown")")
// → "The value is unknown"
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X