Swift容器的可变性浅吗?还是可以将元素更改为原位? [英] Is the mutability of Swift containers shallow? Or can an element be mutated in place?
问题描述
我在Set
中有一个对象集合.对象的类型遵循GeneratorType
,所以我有一个变异方法next
.尽管我可以通过添加/删除元素来对集合进行变异,但是我不知道如何对元素进行变异.同时使用for-in
语句和forEach
方法会给出有关元素不可更改的错误. Swift容器的可变性浅吗?
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?
有没有一种方法可以在包含的元素上调用变异方法?除Set
以外,它是否还适用于其他采集/序列类型? (我所做的更改将更改每个对象的哈希,也许不允许我影响这样的集合.)
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.)
推荐答案
这种情况类似于对字典值之一进行变异的情况,其中该值是一种值类型.即使您对字典的引用是var
引用,也无法做到.通常,您只需拉出值,对其进行变异,然后再放回去:
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
您的Set的工作原理类似.
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.
这里要记住的是没有值类型,例如一个结构,真正是可变的.我们说的好像是这样,Swift的mutating
函数也是如此,但是变异实际上包括将新值分配回引用中.这就是为什么为什么引用必须为var
.因此,没有任何值类型的突变.
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"}
这篇关于Swift容器的可变性浅吗?还是可以将元素更改为原位?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!