Is the mutability of Swift containers shallow? Or can an element be mutated in place?

余生颓废 提交于 2020-01-05 12:57:48

问题


I have a collection of objects in a Set. The objects' type follows GeneratorType, so I have a mutating method next. Although I can mutate the set by adding/removing elements, I don't know how to mutate an element. Using both for-in statement and the forEach method give errors about the element being immutable. Is the mutability of Swift containers shallow?

Is there a way to call a mutating method on a contained element? Does it work for other collection/sequence types besides Set? (My changes would change each object's hash, and maybe I'm not allowed to affect a set like that.)


回答1:


The situation is similar to that of mutating one of a dictionary's values, where that value is a value type. You can't do it, even if your reference to the dictionary is a var reference. Typically, you'll just pull the value out, mutate it, and put it back again:

var d = ["key":"hell"]
var val = d["key"]!
val.append(Character("o"))
d["key"] = val

Your Set works similarly.

var s = Set(["hell"])
var val = s.remove("hell")!
val.append(Character("o"))
s.insert(val)

There are other ways to notate that, but in effect they amount to the same thing.

The thing to keep in mind here is that no value type, e.g. a struct, is truly mutable. We speak of it as if it were, and so does Swift with its mutating functions, but mutation actually consists of assigning a new value back into the reference. That is why the reference must be a var. There is thus no such thing as mutation in place for any value type.

Now, of course, with a reference type, e.g. a class, the situation is completely different:

let s = Set([NSMutableString(string:"hell")])
s.first!.appendString("o")
s // {"hello"}


来源:https://stackoverflow.com/questions/36000869/is-the-mutability-of-swift-containers-shallow-or-can-an-element-be-mutated-in-p

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!