ara*_*ker 13 getter getter-setter swift computed-properties swiftui
我正在尝试重用一段较旧的 Swift 代码,但收到错误“无法在不可变值上使用 mutating getter: 'self' 是不可变错误”。Xcode 想要在 func 之前添加“mutating”,并提供通过“修复”来做到这一点。所以错误消失了,但仍然保留在“文本”语句中。
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
Run Code Online (Sandbox Code Playgroud)
Moj*_*ini 13
因为当您x在 struct 内部调用时,尚不清楚它contentView本身是否可变。实际上,值类型 只有在定义为var.
因此,在结构体内部的构建器函数中使用它之前,您应该使用不可变值包装它。
像这样:
func xValue() -> Double {
var mutatableSelf = self
return mutatableSelf.x
}
var body: some View {
VStack {
Text("\(xValue())")
}
}
Run Code Online (Sandbox Code Playgroud)
Hon*_*ney 13
This has nothing to do with SwiftUI. It's about a design Swift is enforcing with its getters. The principle is:
The getters should not mutate the object. Because developers may not be expecting that. They should only expect a change when you're using the setter or calling a mutating function. A getter is neither of them.
The following example works as expected:
struct Device {
var isOn = true
}
let x = Device()
let y = Device()
y.isOn // Doing such will not cause the object to mutate.
Run Code Online (Sandbox Code Playgroud)
Yet the following example, the getter will have a side-effect. The Swift architecture just doesn't allow it.
struct Device2 {
var x = 3
var isOn: Bool {
x = 5
return true
}
}
let a = Device2()
let b = Device2()
a.isOn // Doing such will mutate the object. a.x will be '5'. While `b.x` will be '3'. Swift doesn't want to allow this.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8884 次 |
| 最近记录: |