2017-07-03 36 views
7

Tôi có một cuốn từ điển của mảng:tham số Generic 'tố' không thể được suy ra khi thêm vào mảng

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

Để cư nó, tôi cố gắng thêm một giá trị cho mảng ở các chỉ số chính xác. Nếu mảng không tồn tại, nó không thành công và tôi thực hiện một mảng mới tại chỉ số đó:

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

Tôi nghĩ rằng tôi sẽ có thể rút ngắn này để:

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

Tuy nhiên, thay vì tôi nhận được lỗi: Generic parameter 'Element' could not be inferred. Tại sao?

+1

Bạn đang sử dụng 'nil-coalescing' vì mục đích sai. Không sử dụng chúng cho ___ bất cứ điều gì, nó chỉ hoạt động___ lý do. – nayem

+0

@nayem Bạn có thể xây dựng? Tại sao điều này sai? – GoldenJoe

Trả lời

5

Swift 3,0

Hãy xem xét các khái niệm đơn giản: -

Trong khi sử dụng if...else trong dòng hoạt động nên đơn hoặc khác chúng ta cần phải phối hoạt động dưới parenthesis để làm nó là một hoạt động đơn lẻ, trong trường hợp của chúng tôi append(val) là một hoạt động nhưng myDict[key] = [val] là nhiều (myDict[key] là một và = nhiệm vụ là một và [val] là một) vì vậy chúng tôi là nhóm chúng thành một đơn bằng cách sử dụng parenthesis.

Theo cách đơn giản hơn, hãy xem xét arithmatic operations sau đây.

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

Ở đây, chúng tôi đang hướng dẫn trình biên dịch không phải là cách mong đợi tại let a.

Cũng xem,

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

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

Đây let c là hướng dẫn sai, lỗi là,

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

Nếu tôi buộc unwrapping các optionals a and b thì lỗi sẽ trở thành,

unexpectedly found nil while unwrapping an Optional value

Vì vậy, hằng số c trở thành,

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

Đó là bạn nên sử dụng parenthesis xung quanh giá trị default.

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

Rất đẹp. Bất kỳ ý tưởng những gì lỗi đang cố gắng giải thích? – GoldenJoe

+1

@GoldenJoe, yeah.lol .. cảm ơn bạn :) –

+1

@GoldenJoe, hãy xem giải thích :) –

5

Nó tốt hơn để làm điều này:

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

Nó loại bỏ các array từ myDict trước khi đột biến, do đó array sẽ là tài liệu tham khảo chỉ vào bộ nhớ của mảng. Bởi vì nó được tham chiếu duy nhất, các hoạt động có thể thay đổi có thể được thực hiện với nó mà không cần phải sao chép bộ nhớ của mảng.

Nếu không có điều này, mỗi cuộc gọi myDict[key]?.append(val) sẽ gây ra thao tác sao chép khi ghi.

Các vấn đề liên quan