В Scala оператор + (k -> v)
на immutable.Map
возвращает новый immutable.Map
с содержимым оригинала, плюс новая пара ключей/значений. Аналогично, в С# ImmutableDictionary.add(k, v)
возвращает новый, обновленный ImmutableDictionary
.
В Swift, однако, Dictionary
появляется только с функцией mutating updateValue(v, forKey: k)
и мутирующим оператором [k:v]
.
Я подумал, может быть, я мог бы сыграть с трюком с flatten()
, но не повезло:
let updated = [original, [newKey: newValue]].flatten()
получает меня
Cannot convert value of type '() -> FlattenCollection<[[String : AnyObject]]>'
to specified type '[String : AnyObject]'
Как создать новый, измененный неизменяемый Dictionary
из содержимого существующего?
Обновление: На основе этого ответа обратите внимание, что словари Swift являются типами значений, а this answer измененная версия, я придумал следующий оператор расширения, но меня это не волнует - похоже, должна быть более чистая альтернативная версия.
func + <K, V>(left: [K:V], right: [K:V]) -> [K:V] {
var union = left
for (k, v) in right {
union[k] = v
}
return union
}
Но, может быть, факт (если я правильно понимаю), что неизменность словарей Swift - это проверка компилятора на let
, а не вопрос разных классов реализации, означает, что это лучшее, что можно сделать?
Обновление # 2: Как указано в Jules answer, изменение неизменяемых словарей, которые специально не оптимизированы для совместного использования состояний между копиями (как Swift словари не представляют) проблемы производительности. Для моего текущего варианта использования (AttributedString
словари атрибутов, которые имеют тенденцию быть довольно небольшими), он все же может упростить некоторые вещи, которые можно сделать достойными, но до тех пор, пока Swift не будет применять неизменный словарь с разделяемым состоянием, это, вероятно, не очень хорошая идея в общий случай - это хорошая причина не иметь его как встроенную функцию.