2016-03-15 27 views
1

我有一个Set中的对象的集合。对象的类型遵循GeneratorType,所以我有一个变异方法next。虽然我可以通过添加/移除元素来改变集合,但我不知道如何改变元素。同时使用for-in语句和forEach方法给出有关该元素是不可变的错误。 Swift容器的可变性很浅吗?Swift容器的可变性浅吗?或者一个元素是否可以进行突变?

有没有办法调用一个包含元素的变异方法?除了Set之外,它还适用于其他收集/序列类型吗? (我的更改会改变每个对象的散列值,也许我不会影响这样的集合。)

+0

什么具体类型是集携带(INT,字符串等如果自定义,指定如果结构或类)? Set是用'let'声明的? – tktsubota

+0

@TroyT,我在'var'顶层对象(游戏场)中使用'var'属性的自定义'struct'。 – CTMacUser

回答

3

这种情况类似于字典值之一的变化,其中值是值类型。即使您对字典的引用是var参考,也不能这样做。通常情况下,您只需将该值拉出,对其进行变异并重新放回:

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

您的设置的工作原理与此类似。

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

还有其他的方式来表明这一点,但实际上它们是相同的东西。

这里要记住的是没有值类型,例如一个结构体,确实是可变的。我们把它说成好像是这样,Swift和它的mutating函数也是如此,但是变异实际上包括将新值分配回参考文献。那是为什么的参考号必须是var。因此没有这样的东西作为的任何值的类型的突变。

当然,现在使用参考类型,例如,一个类,情况完全不同:

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

感谢您的耐心等待,我现在完成了我的答案。 :) – matt

+0

哦,我没有看到。我睡着了,尝试了除Set之外的其他容器,最初的猜测是Swift不会让我无视容器索引。 (一个'Set'使用它自己的元素作为索引。)我可以改变一个'Dictionary'的值(但不是键)。对于一个'Array',我不得不使用'enumerate',只使用索引,并以这种方式操作元素;通过'forEach'直接操作仍然设置为'let'模式。尽管'forEach'中使用'(var element)in'被编译器接受,实际的变异将被忽略(通过稍后的检查证明)! – CTMacUser

+0

似乎对每个方法的(im)可变性和/或值对参考C++的精细控制确实有其优势。如果你不喜欢Swift在这些问题上的默认值,那么它大部分时间都会对抗你。 – CTMacUser

相关问题