2017-10-05 3 views
1

Je suis la mise en œuvre CoreML à Swift 4, et est ici un problème avec if let que je fais face à ce moment,si laissez pas déballer une valeur facultative à Swift 4.0

var pixelBuffer : CVPixelBuffer? 
    var model: Inceptionv3? 

    if let prediction = try? self.model?.prediction(image: pixelBuffer!) 
    { 
     classifier.text = "I think this is a \(String(describing: prediction.classLabel))." //ERROR..!!! 
    } 

Valeur type facultatif 'Inceptionv3Output?' pas déballé; avez-vous signifie d'utiliser '!' ou '?'?

Je sais ce que signifie l'erreur et comment la résoudre. Ce que je ne comprends pas, c'est pourquoi cela apparaît-il?

Dans le code ci-dessus j'utilise if let pour obtenir une valeur non enveloppée de prediction. Et encore il me demande de le déballer explicitement.

Toute sorte d'aide est appréciée.

Répondre

3

Réponse courte:

Vous créez une liaison double, enveloppé facultatif en raison de la combinaison de en option chaînage et l'utilisation de try?. Donc, if let ne fait que déballer la première couche de double facultatif enveloppé en vous laissant avec une variable optionnelle.


Pourquoi est-ce?

try? est utilisé avec un appel que lance. Si l'appel renvoie une erreur, l'expression renvoie nil. Si l'appel réussit, la valeur est enveloppée dans un facultatif.

Vous utilisez une chaîne en option pour appeler prediction sur model. Si le modèle est nil, le résultat de la chaîne optionnelle est nil. Note, ce résultat n'a pas jeter donc le résultat est enveloppé dans un optionnel par try? résultant en Optional(nil) ce qui n'est pas la même chose que nil. Si l'appel à la prédiction réussit, le résultat est enveloppé dans une option en raison de la chaîne en option, et enveloppé dans un nouveau en option en raison de la try?.

Donc, il y a trois résultats possibles:

  1. modèle n'est pas nil et appel à prediction renvoie un résultat valide de type Inceptionv3Output sans jeter. Ce résultat devient Inceptionv3Output? en raison de la chaîne en option et Inceptionv3Output?? en raison du try?. Le modèle n'est pas nil, mais l'appel à prediction génère une erreur. Le résultat du try? est nil en raison du lancer. Le modèle est nil. Le résultat de la chaîne en option est nil, et ce résultat est enveloppé dans en option à cause de try ? résultant en Optional(nil).

Ainsi, votre if let est Déballer une valeur de type Inceptionv3Output?? qui signifie prediction a le type Inceptionv3Output?. Le if let réussit si l'appel n'est pas lancé. Si le model est nil, alors prediction sera nil, sinon il contient la valeur encapsulée qui est le résultat de l'appel prediction sur le model.

+0

Merci beaucoup d'être clair .. :) – PGDev

+0

De rien. C'est logique, mais un peu difficile à expliquer. – vacawama

0

Essayez-le déballer ainsi:

if let model = model, 
    let prediction = try? model.prediction(image:pixelBuffer!) { 
    // Your code here 
} 

Vous ne pouvez pas utiliser try? avec une expression qui n'a pas throw. Donc, vous êtes obligé de déballer model juste pour vous assurer que l'expression throws.

Dans le cas model était nil, l'expression n'exécutera prediction(image:), et c'est la raison pour laquelle vous êtes à déballer model avant d'utiliser try?

+0

Mais quel est le besoin de le faire si j'utilise un chaînage optionnel pour cela? – PGDev

+1

@PGDev Je suppose que parce que vous utilisez 'try?', Vous devez vous assurer qu'il y a du code qui pourrait provoquer une erreur. Donc, si vous utilisez 'self.model? .', ce code pourrait ne pas générer d'erreur. Vous êtes donc obligé de déballer le modèle avant d'utiliser 'try?'. – TawaNicolas

+0

Comment fonctionne l'utilisation? affecte la gestion des exceptions? – PGDev