人们如何处理迭代 Swift 结构值类型属性?
Posted
技术标签:
【中文标题】人们如何处理迭代 Swift 结构值类型属性?【英文标题】:how do people deal with iterating a Swift struct value-type property? 【发布时间】:2019-05-29 13:46:07 【问题描述】:这是人们必须一直出现的明显情况:
struct Foundation
var columns : [Column] = [Column(), Column()]
struct Column : CustomStringConvertible
var cards = [Card]()
var description : String
return String(describing:self.cards)
struct Card
var f = Foundation()
for var c in f.columns
c.cards.append(Card())
该代码是合法的,但当然它对f
没有影响,因为var c
仍然是一个副本——f
的实际columns
不受影响。
我没有任何困难理解为什么会发生这种情况。我的问题是人们通常对此做什么。
显然,我可以通过将 Column 声明为 class 而不是 struct 来解决整个问题,但人们通常会这样做吗? (我试图遵循一种精神上的限制,即当不需要动态调度/多态性/子类化时,应该避免类;也许我把它带得太远了,或者人们通常会做其他事情,比如使用inout
不知何故。)
【问题讨论】:
在 Swift 论坛 (forums.swift.org/t/idea-mutatingforeach-for-collections/18442 & forums.swift.org/t/in-place-map-for-mutablecollection/11111) 上讨论了添加“改变每个元素”方法。但是我相信最终目标是在我们拥有适当的所有权模型allowing you to say something likefor inout c in f.columns
后在语言级别实现这一点。
我不知道人们一般都做什么。我所看到的“解决方法”是迭代索引:for i in f.columns.indices f.columns[i].cards.append(Card())
@MartinR 这是一个很好的折衷方案,你愿意给出这个答案吗?
@Hamish Hilarious 因为我当然尝试输入for inout
,即使我知道它不会编译。 :)
【参考方案1】:
从 Swift 4 开始,折衷方案是迭代可变集合的索引而不是元素本身,这样
for elem in mutableCollection
// `elem` is immutable ...
或
for var elem in mutableCollection
// `elem` is mutable, but a _copy_ of the collection element ...
变成
for idx in mutableCollection.indices
// mutate `mutableCollection[idx]` ...
在你的例子中:
for idx in f.columns.indices
f.columns[idx].cards.append(Card())
正如@Hamish 在 cmets 中指出的那样,未来版本的 Swift 可能会实现 mutating iteration,从而使
for inout elem in mutableCollection
// mutate `elem` ...
可能。
【讨论】:
以上是关于人们如何处理迭代 Swift 结构值类型属性?的主要内容,如果未能解决你的问题,请参考以下文章
Swift 3 / 如何处理嵌套的 NSDictionaries,因为“Any 类型的值没有成员值”