我想澄清一下我是否理解了以下概念。
假设我的目标是将String
"Good morning, Mike"
存储到变量var sayGoodMorningToUser
中。
String由两个变量组成,即
var greeting = "Good morning, "
var username = "Mike"
如果我使用存储属性与计算属性有什么区别,换句话说:
var sayGoodMorningToUserStored = greeting + username
VS
var sayGoodMorningToUserComputed:String {
return greeting + username
}
我在这两种方法之间看到的唯一区别是,任何人都可以轻松直接地更改sayGoodMorningToUserStored的值,例如:通过写作
var sayGoodMorningToUserStored = "myNewChangedValue"
而变量sayGoodMorningToUserComputed不能直接修改,因为它不能简单地将其设置为新的String值:
var sayGoodMorningToUserComputed = "Hallo" //this would cause an error
否则我无法理解为什么人们计算变量而不是简单地写
var sayGoodMorningToUserStored = greeting + username.
任何人都可以解释我是否理解正确吗?或者计算变量与存储变量还有其他优点吗?
我想将我的问题仅限于可获取的变量,因为在这里讨论可设置的变量将超出范围。
答案 0 :(得分:2)
你的例子的不同之处在于:
var sayGoodMorningToUserStored = "myNewChangedValue"
和
var sayGoodMorningToUserStored = greeting + username
初始化类时会设置,而这个:
var sayGoodMorningToUserComputed:String {
return greeting + username
}
每次访问该属性时都会对进行评估。
简单示例是一个具有firstName
和lastName
但又需要fullName
的类。使用普通属性时,每次更新firstName
或lastName
时,您还必须更新fullName
以使其匹配。使用计算属性,每次访问fullName
时,您都将获得最新信息。
答案 1 :(得分:1)
var sayGoodMorningToUserComputed: String {
return greeting + username
}
sayGoodMorningToUserComputed
就像一个函数一样。如果对greeting
或username
进行了更改,则sayGoodMorningToUserComputed
将返回最新结果,该结果将是当前值的串联。
如果要确保根据其依赖项的最新值(greeting
和username
)计算返回值,则可能需要使用此项。
如果两个依赖项都是final
,那么编译器很可能会将此计算属性优化为存储属性,因为它知道依赖项无法更改
var sayGoodMorningToUserStored = greeting + username
sayGoodMorningToUserStored
只是一个变量,没有什么特别之处。但是,只要初始化包含范围,它就只设置一次。它被计算一次,存储并保持不变,直到它被外部源覆盖。因此,如果greeting
或username
发生变化,则对sayGoodMorningToUserStored
没有影响,因为它是根据旧值计算并存储的。
如果您希望通过缓存依赖关系不变的计算结果来提高性能,那么您可能希望使用此方法。