2017-08-06 46 views
1

我有創造出有4個數據成員訪問時,它不應該是零類測試模型(指返回默認值)可選值的方式

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 */ 

獲得輸出

Jd 
nil 
0.0 

預計產量

Jd

ABC/應該返回的ABC,而不是零/

0.00/兩個小數點complulsury/

我在

實際上是說,如果我給你零值變量,然後它應該保持它的默認值而不用寫這個可選的鏈接?? 「abc」 in構造函數

+0

如果您的'dictionary'可以返回零,那麼您必須手動將其更改爲設置任何默認值,如問題所示。沒有出路。 – adev

+0

okey我想我必須刪除這個問題,因爲沒有辦法來優化以上問題 –

+0

所以你們應該刪除你的答案以及 –

回答

0

你似乎已經在這裏問了兩個不同的問題。關於雙打的第一個已經由adev回答了。我將回答第二個問題,即:

如果我將nil賦值給變量,那麼它應該保持其默認值而不寫這個可選的鏈接?「ABC」在構造

如果你想這樣做,那麼就意味着該變量不應該是可選的了,因爲nil不是它的有效值之一。使該變量成爲非可選類型並將其設置爲默認值。

class TestingModel{ 

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

你真的不能避免在構造使用??因爲詞典的本質。如果密鑰不存在,它們將始終返回nil值。你必須檢查它。無論如何,這是沒有意義的。想象一下這樣的事情:

someVariable = nil // someVariable is now 0 

這是非常混亂。 someVariable爲0,即使看起來nil已分配給它。

解決方法是添加字典擴展。像這樣的:

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

但我仍然建議您使用??來代替。

+0

爲什麼extesion字典不是更好的方式任何理由(它看起來更可讀的格式) –

+0

@JaydeepVyas因爲擴展基本上是'??'操作符的包裝。已經有'??'了,你不認爲這個擴展是「重新發明輪子」嗎?任何有一定經驗的人都知道''''做了什麼,你現在的代碼非常清晰。沒有必要想辦法避免使用'??'。畢竟,「??」完全是爲了這個目的而設計的。 – Sweeper

+0

我在回答中提到了現在已刪除的聊天室中的相同內容。他不能避免''''。 – adev

1

price是一個Double類型,您要做的是將該double值打印到2個小數位。那麼你應該利用以下內容。

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

此打印:

0.00

如果您計劃四捨五入爲十進制的地方,然後又在上面的代碼將返回。但是,如果你需要它來圓並返回一個double類型,那麼你可以查看基於更新後的問題this answer

,我建議使用型號如下:

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

'0'和'0.00'有什麼區別?對於'Double'類型都是一樣的。只有在打印時才告訴它顯示所需的小數點數。 – adev

+0

我覺得你在控制檯中打印的字符串和你的Double類型之間感到困惑。 double不能控制'.'後面有多少個零。只有在打印或轉換爲字符串時,纔可以打印所需的零數。 – adev

+0

那是因爲你做了一個很大的浮點數的四捨五入。但對於'0',你不能那樣做。它會返回'0.0' – adev

0

我認爲我們可以消除這個問題由改變它擴展雙精度值的喜歡這個

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()) 
    } 

} 

用法

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

輸出

0.00 100.12 0.05