2017-07-03 39 views
7

Mam słownika tablic:Generic parametr „Element” nie można wywnioskować po dodaniu do tablicy

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

aby wypełnić go, staram się dodać wartość do tablicy w odpowiednim indeksie. Jeśli tablica nie istnieje, to nie powiedzie się i zrobię nową tablicę na tym indeksie:

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

myślę, że powinienem być w stanie skrócić to do:

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

Jednak zamiast otrzymuję błąd: Generic parameter 'Element' could not be inferred. Czemu?

+1

Używasz 'zerowego koalescingu' dla złego celu. Nie używaj ich do ___ cokolwiek, działa tylko z tego powodu. – nayem

+0

@nayem Czy możesz rozwinąć? Dlaczego to jest złe? – GoldenJoe

Odpowiedz

5

Swift 3,0

Rozważmy prostą koncepcję: -

Podczas korzystania if...else w jednej linii operacje powinny być jedno- albo musimy kolega operacji pod parenthesis aby jako pojedyncza operacja, w naszym przypadku append(val) jest pojedynczą operacją, ale myDict[key] = [val] jest wielokrotnością (jest wielokrotnością () jest jednym i = przydziałów to jeden i [val] jest jeden), więc jesteśmy grupując je w jeden przy użyciu parenthesis.

W bardziej prosty sposób należy rozważyć następujące 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 

Niniejszym instruujemy kompilator w sposób nieprzewidziany pod numerem let a.

także zobaczyć,

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

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

Tutaj let c jest błędna instrukcja, błąd jest

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

Jeśli mogę zmusić unwrapping się optionals a and b, wtedy błąd będzie,

unexpectedly found nil while unwrapping an Optional value

Stała stała c staje się

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

To należy użyć parenthesis wokół wartości default.

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

Nice. Masz pojęcie, co ten błąd próbuje wyjaśnić? – GoldenJoe

+1

@GoldenJoe, yeah.lol .. dziękuję :) –

+1

@GoldenJoe, zobacz wyjaśnienie :) –

5

Lepiej to zrobić:

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

usuwa array z myDict przed mutacją, tak że array będzie tylko odniesienie do pamięci Array. Ponieważ jest to unikalne odniesienie, można wykonywać do niego operacje zmienne, bez konieczności kopiowania pamięci tablicy.

Bez tego każde wywołanie myDict[key]?.append(val) powoduje operację kopiowania przy zapisie.