2017-07-03 36 views
7

時,我有陣列的字典中推斷:通用參數「元素」不能添加到陣列

var myDict : [String:[SomeObj]] = [:] 

來填充它,我嘗試將值正確的索引處添加到陣列中。如果數組不存在,它失敗,我提出一個新的數組索引:

if myDict[key]?.append(val) == nil { 
    myDict[key] = [val] 
} 

我想我應該能縮短這:

myDict[key]?.append(val) ?? myDict[key] = [val] 

然而,而是我得到的錯誤:Generic parameter 'Element' could not be inferred。爲什麼?

+1

您正在使用'nil-coalescing'來達到錯誤目的。不要將它們用於___什麼,它只是起作用的原因。 – nayem

+0

@nayem你能詳細說明一下嗎?爲什麼這是錯的? – GoldenJoe

回答

5

雨燕3.0

考慮簡單的概念: -

雖然單行使用if...else的操作應該是單一的,否則,我們需要交配parenthesis下操作,使它作爲單個操作,在我們的案例中,append(val)是單個操作,但myDict[key] = [val]是多個(myDict[key]是1和=作業是一個,[val]是一個),所以我們將它們分組使用parenthesis

以更簡單的方式考慮以下arithmatic operations

//I need 10-5 = 5 
let a = 2*4+2-4-3*5 
print(a) // -9 
//so we can seprate by() 
let b = ((2*4)+2)-(4-3)*5 
print(b) //5 

在這裏,我們指示編譯器不是預期的方式let a

而且看,

let a:Int? = nil 
var b:Int? = nil 
let d = 10 

let c = a ?? 10 * b ?? d 

這裏let c是錯誤的指令,錯誤是,

Value of optional type 'Int?' not unwrapped; did you mean to use '!' or '?'?

如果我強迫unwrappingoptionals a and b,那麼誤差將變得

unexpectedly found nil while unwrapping an Optional value

所以常數c成爲,

let c = a ?? 10 * (b ?? d) //100 

這就是你應該使用parenthesis圍繞default值。

myDict[key]?.append(val) ?? (myDict[key] = [val]) 
+0

不錯。任何想法是什麼錯誤試圖解釋? – GoldenJoe

+1

@GoldenJoe,yeah.lol ..謝謝:) –

+1

@GoldenJoe,看到解釋:) –

5

這是更好地做到這一點:

var array = myDict.removeValue(forKey: key) ?? [] 
array.append(item) 
myDict[key] = array 

它消除了arraymyDict突變前,讓array將是數組的內存的唯一參考。由於它是唯一引用的,因此可以對其執行可變操作,而無需複製陣列的內存。

沒有這個,每個myDict[key]?.append(val)調用導致寫入時複製操作。