无法在不可变值上使用变异吸气剂:“自身”是不可变错误

时间:2019-08-01 20:04:44

标签: swiftui

我正在尝试重用旧版的Swift代码,但遇到错误“无法对不可变值使用变异吸气剂:“自身”是不可变错误”。 Xcode希望在功能之前添加“变异”,并提出通过“修复”来实现。因此错误在那里消失了,但仍然停留在“文本”语句中。

import SwiftUI

struct ContentView: View {

     typealias PointTuple = (day: Double, mW: Double)
    let points: [PointTuple] = [(0.0, 31.98), (1.0, 31.89), (2.0, 31.77), (4.0, 31.58), (6.0, 31.46)]

    lazy var meanDays = points.reduce(0) { $0 + $1.0 } / Double(points.count)
    lazy var meanMW   = points.reduce(0) { $0 + $1.1 } / Double(points.count)

    lazy var a = points.reduce(0) { $0 + ($1.day - meanDays) * ($1.mW - meanMW) }
    lazy var b = points.reduce(0) { $0 + pow($1.day - meanDays, 2) }

    lazy var m = a / b
    lazy var c = meanMW - m * meanDays        
    lazy var x : Double = bG(day: 3.0)
    lazy var y : Double = bG(day: 5.0)
    lazy var z : Double = bG(day: 7.0)

    mutating func bG(day: Double) -> Double {
        return m * day + c
    }

    var body: some View {
        VStack {
            Text("\(x)")
            Text("\(y)")
            Text("\(z)")
        }
    }
}

#if DEBUG
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
#endif

2 个答案:

答案 0 :(得分:6)

这与boolean无关。这是关于Swift正在使用其吸气剂强制执行的设计。原理是:

吸气剂不应使对象突变。因为开发人员可能并不期望这样。仅当您使用 setter 或调用 muting 函数时,他们才应该期待更改。吸气剂都不是他们。

以下示例按预期方式工作:

list.stream()
  .forEach(item -> item.type.equals("Good") && item.expired == false);

但是,在下面的示例中,吸气剂会产生副作用。 Swift架构只是不允许这样做。

list.stream()
  .filter(item -> item.type.equals("Good") && item.expired == false)
  .findFirst()
  .get()

答案 1 :(得分:3)

由于在结构内部调用x时,尚不清楚contentView本身是否可变。实际上,只有在将值类型定义为var的情况下,该值类型才会变得可变。

因此,在将其用于struct内部的builder函数之前,应将其包装为不可变的值。

像这样:

func xValue() -> Double {
    var mutatableSelf = self
    return mutatableSelf.x
}

var body: some View {
    VStack {
        Text("\(xValue())")
    }
}