In Scala, l'operatore + (k -> v)
su immutable.Map
restituisce un nuovo immutable.Map
con il contenuto dell'originale, più la nuova coppia chiave/valore. Analogamente, in C#, ImmutableDictionary.add(k, v)
restituisce un nuovo ImmutableDictionary
aggiornato.Come faccio ad "accodare" a un dizionario immutabile in Swift?
In Swift, tuttavia, Dictionary
appare solo per la funzione di muting updateValue(v, forKey: k)
e l'operatore di muting [k:v]
.
ho pensato che forse avrei potuto giocare un po 'di trucco con flatten()
, ma senza fortuna:
let updated = [original, [newKey: newValue]].flatten()
mi viene
Cannot convert value of type '() -> FlattenCollection<[[String : AnyObject]]>'
to specified type '[String : AnyObject]'
Come faccio a creare una nuova, modificata immutabile Dictionary
dai contenuti di un quello esistente?
Aggiornamento: Sulla base di 's nota che Swift dizionari sono tipi di valore, e this answer' this answer versione mutevole s, mi si avvicinò con il seguente operatore estensione, ma io non sono entusiasta - sembra che ci debba essere un'alternativa più pulita e pronta all'uso.
func + <K, V>(left: [K:V], right: [K:V]) -> [K:V] {
var union = left
for (k, v) in right {
union[k] = v
}
return union
}
Ma forse il fatto (se ho capito bene), che l'immutabilità di dizionari Swift è un controllo sulla compilatore let
piuttosto che una questione di differenti classi di implementazione significa che questo è il meglio che si può fare?
Aggiornamento # 2: Come osservato in Jules's answer, modificando dizionari immutabili che non sono specificatamente ottimizzate per condividere lo stato tra copie (come Swift dizionari non sono) presenta problemi di prestazioni. Per il mio caso d'uso corrente (i dizionari degli attributi AttributedString
, che tendono ad essere piuttosto piccoli) può ancora semplificare alcune cose che valga la pena di essere fatte, ma fino a quando Swift non implementa un dizionario immutabile con stato condiviso probabilmente non è una buona idea in generale case - che è una buona ragione per non averlo come funzionalità integrata.
Sembra che qualcuno stia costruendo una biblioteca per fare proprio questo https://github.com/tLewisII/ImStructures (Disclaimer: non l'ho controllato.) –
* che l'immutabilità dei dizionari Swift è un controllo del compilatore [. ..] diverse classi di implementazione * Questo è sbagliato. I dizionari sono implementati come strutture e ciò significa che sono (fondamentalmente) passati per copia. Qualsiasi valore di struct che è memorizzato in una variabile 'let' è immutabile, quindi non è possibile richiamare i metodi' mutating' su di esso in quanto cambierebbero il valore. Se assegni un dizionario (qualsiasi struttura) ad una variabile 'var', questo viene copiato! Quindi hai un dizionario diverso con una nuova posizione di memoria. – idmean