2017-08-06 1 views
1

je créer le modèle de classe d'essai qui a 4 DataMember il ne devrait pas être nul lors de l'accès (signifie la valeur par défaut de retour)Valeur facultative dans rapide 3 voies optimisé

extension Double { 
    /// Rounds the double to decimal places value 
    func roundTo(places:Int = 2) -> Double 
    { 
     let divisor = pow(10.00, Double(places)) 
     return (self * divisor).rounded()/divisor 
    } 
} 
class TestingModel{ 

    var id : String! 
    var name : String! = "abc" /*It is not working*/ 
    var price : Double! = 0.00 
    var uniqueId : Int! = 1 


    /** 
    * Instantiate the instance using the passed dictionary values to set the properties values 
    */ 
    init(dictionary: [String:Any]) 
    { 
     id = (dictionary["id"] as? String) ?? "" //I dont want to do like this way 
     name = dictionary["name"] as? String 
     price = (dictionary["price"] as? Double)?.roundTo() ?? 0.00 
     uniqueId = dictionary["unique_id"] as? Int 
    } 

} 

let t:TestingModel = TestingModel.init(dictionary: ["x id" : "x012y12345z45","x name":"test1","x price":100.0,"uniqueId":1236.0]) 
let testString = "Jd " + t.id 
print(testString) //Perfect 
print(t.name) 
print(t.price) /* Only one decemal point is printed */ 

Obtenir de sortie

Jd 
nil 
0.0 

sortie prévue

Jd

abc/doit retourner abc au lieu de zéro/

0.00/Deux virgule complulsury/

Ce que je veux dire en fait dans

si j'attribuer une valeur nulle à la variable puis il devrait rester avec sa valeur par défaut sans écrire ceci Chaînage optionnel ?? "abc" dans le constructeur

+0

Si votre dictionnaire peut renvoyer zéro, alors vous devez le changer manuellement pour définir les valeurs par défaut comme indiqué dans votre question elle-même. Il n'y a pas moyen de sortir. – adev

+0

ok je pense que je dois supprimer cette question, car il n'y a aucun moyen d'optimiser la question ci-dessus –

+0

alors les gars s'il vous plaît supprimer vos réponses ainsi –

Répondre

0

Vous semblez avoir posé deux questions différentes ici. Le premier concernant les doubles a déjà été répondu par adev. Je vais répondre à la deuxième, qui est:

si j'attribue une valeur nulle à variable alors il devrait rester avec sa valeur par défaut sans écrire ce chaînage facultatif ??« Abc » dans le constructeur

Si vous voulez faire cela, alors cela signifie que la variable ne doit pas être en option du tout, comme nil n'est pas une de ses valeurs valides. Faites de la variable un type non facultatif et donnez-lui une valeur par défaut.

class TestingModel{ 

    var id : String = "" 
    var name : String = "abc" 
    var price : Double = 0.00 
    var uniqueId : Int = 1 
} 

Vous ne pouvez pas vraiment éviter l'utilisation ?? dans le constructeur en raison de la nature des dictionnaires. Ils renverront toujours une valeur nil si la clé n'existe pas. Vous devez le vérifier. Cela n'a pas de sens même si c'est possible de toute façon. Imaginez quelque chose comme ceci:

someVariable = nil // someVariable is now 0 

Ceci est extrêmement déroutant. someVariable est 0, même s'il semble que nil lui soit affecté.

Une solution de contournement consiste à ajouter une extension de dictionnaire. Quelque chose comme ceci:

extension Dictionary { 
    func value(forKey key: Key, defaultValue: Value) -> Value { 
     return self[key] ?? defaultValue 
    } 
} 

Mais je recommande toujours que vous utilisez à la place ??.

+0

pourquoi explaination extesion Dictionnaire n'est pas meilleure façon aucune raison (il semble plus lisible) –

+0

@JaydeepVyas Parce que l'extension est essentiellement une enveloppe de l'opérateur '' de ??. Il y a déjà '??', ne pensez-vous pas que l'extension est une sorte de "réinventer la roue"? Toute personne qui a un certain niveau d'expérience dans swift sait ce que «fait» et votre code actuel est assez clair. Il n'y a pas besoin de penser à un moyen d'éviter d'utiliser '??'. '??' est conçu pour exactement ce but après tout. – Sweeper

+0

J'avais mentionné la même chose dans la salle de discussion maintenant supprimée sur ma réponse. Il ne peut pas éviter '??'. – adev

1

price est un type Double et ce que vous demandez est d'imprimer cette double valeur à 2 décimales. Ensuite, vous devriez utiliser ce qui suit.

let a = 0.0 
print(String(format: "%.2f", a)) 

cette impression:

0,00

Si vous prévoyez d'arrondir à la décimale des lieux, puis aussi le code ci-dessus le retourner. Mais si vous en avez besoin pour arrondir et retourner un type double alors vous pouvez vérifier this answer

en fonction de votre question à jour, je vous suggère d'utiliser le modèle comme suit:

class TestingModel{ 
    var id : String = "" 
    var name : String = "abc" 
    var price : Double = 0.0 
    var uniqueId : Int = 1 

    /** 
    * Instantiate the instance using the passed dictionary values to set the properties values 
    */ 
    init(dictionary: [String:Any]) 
    { 
     id = (dictionary["id"] as? String) ?? "" 
     name = dictionary["name"] as? String ?? "abc" 
     price = (dictionary["price"] as? Double) ?? 0.0 
     uniqueId = dictionary["unique_id"] as? Int ?? 1 
    } 
} 
+0

Quelle est la différence entre '0' et' 0.00'? Pour un type 'Double', les deux sont identiques. Seulement en imprimant vous lui dites pour montrer le nombre de points décimaux requis. – adev

+0

Je pense que vous êtes confus entre une chaîne imprimée en console et votre type Double. double ne contrôle pas le nombre de zéros présents après '.'. Seulement lors de l'impression ou de la conversion en chaîne, vous pouvez obtenir le nombre requis de zéros imprimés. – adev

+0

C'est parce que vous faites l'arrondi sur un nombre flottant si grand. Mais pour '0', vous ne pouvez pas faire cela. Il retournera '0.0' – adev

0

Je pense que nous pouvons éliminer le problème de double valeur par l'extension changer comme ça

extension Double { 
    /// Rounds the double to decimal places value 
    func roundTo(places:Int = 2) -> Double 
    { 
     let divisor = pow(10.00, Double(places)) 
     return (self * divisor).rounded()/divisor 
    } 
    var stringValue:String! 
    { 
     return String(format:"%.2f",self.roundTo()) 
    } 

} 

Utilisation

let doubleDemo = 0.0 
let doubleDemo2 = 100.123 
let doubleDemo3 = 0.0526 
print(doubleDemo.stringValue) 
print(doubleDemo2.stringValue) 
print(doubleDemo3.stringValue) 

sortie

0,00 100,12 0,05