【问题标题】:Strange syntax when try to iterate through the array of structs in swift尝试快速遍历结构数组时出现奇怪的语法
【发布时间】:2015-10-30 14:20:10
【问题描述】:

我有一个简单的结构数组

var fields: [ProfileField]?

当我尝试遍历此数组时,swift 会在此代码上显示错误:

guard let _fields = fields else {return}
for field in _fields {
}

错误是:

Cannot use mutating getter on immutable value: 'field' is a 'let' constant

而且这段代码编译得很好:

for var field in _fields {
}

为什么我需要将field 声明为var

【问题讨论】:

  • @MikePollard guard let _fields = fields else {return}
  • 我认为你需要在你的 for 循环中透露你在做什么
  • 我猜你正在做一些变异 field
  • 是的,当你的结构是一个类时,它就是一个引用。现在它是一个结构和一个值,如果你用 let 声明它就不能改变。

标签: ios swift struct


【解决方案1】:

Swift 中的“mutating getter”是其get 块具有mutating 修饰符的属性。例如,如果您的 ProfileField 看起来像这样:

struct ProfileField {
    var accessCount: Int = 0

    var x: Int {
        mutating get {    // ← mutating getter here
            accessCount++
            return x
        }
    }
}

...那么这段代码会产生“Cannot use mutating getter on immutable value”错误:

for field in _fields {
    print(field.x)
}

尽管它看起来不像 field.x 修改了 field,但它确实:它增加了 accessCount。这就是为什么你必须说var field 才能使字段可变。 (for循环迭代器默认为let。)

没有看到您的 ProfileField 或 for 循环的主体,就不可能确切说明为什么会发生这种情况。如果您没有在ProfileField 本身中使用mutating get,它可能发生在嵌套在ProfileField 内的结构中。

【讨论】:

  • 太棒了!非常感谢您的“即使” - 现在我知道 accessCount 正在改变!最好的!
  • 很高兴它有帮助。进一步令人惊讶的细节(当你考虑它时这是有道理的):导致编译错误的不是accessCount++,而是单词mutating本身。如果一个函数修改了结构,你必须声明它mutating,但反之则不然。你可以声明 mutating 只是为了保留修改结构的权利,即使你没有。这是一个 API 选择。
猜你喜欢
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
  • 2023-02-26
  • 1970-01-01
  • 2021-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多