Skip to content
Swift里的存储属性 & 计算属性
SwiftUISwift12/17/2023

报错信息

error

🔴 Cannot use mutating getter on immutable value: 'self' is immutable

问题代码

Untitled

首先根据报错的提示,不能在不可变值上使用可变getter: 'self'是不可变的。一开始我理解错了,因为报错的是使用的地方,我就以为是报错行的问题,但后来发现不管在哪用都会报错,所以其实是变量定义的有问题。

我所希望的result是一个计算属性,即是跟随isOn计算出来的,在查询过后我发现有着很大的问题,我原先错误的写法实际上还是一个存储属性,只不过是在初次赋值时计算了一次,后续不会再进行计算。

swift
lazy var result:Bool = isOn ? true : false
lazy var result:Bool = isOn ? true : false

计算属性的正确写法应该是这样:

swift
var result:Bool {
	return isOn ? true : false
}
var result:Bool {
	return isOn ? true : false
}

在修改后确实没有报错了。

mutating & immutable

虽然问题解决了,但是其实并没有理解报错的问题,我们再回到报错的信息当中,

报错可以分为两部分:

  • Cannot use mutating getter on immutable value
  • 'self' is immutable

第二部分很好理解,View是一个struct类型,也即值类型,而不是引用类型,当我们试图修改它的属性时实际上是创建了一个新的视图,而不是直接修改原始视图。 @State 关键字则是将值存储在一个单独的特殊位置,并且当该值发生更改时,SwiftUI会重新构建视图。所以当我们需要在View中通过变量控制View的变化,就需要设置为@State@Bind

由于直接使用var是不能驱动view的更新的,所以还有一个解决方案是把result写在body里,这样当isOn修改驱动view更新时会重新计算内部的变量,也可以实现计算效果。

而第一部分为什么lazy会引引发这个问题呢。。。 还有待解决

  • [x]: lazy为什么会让变量变成mutating getter