【问题标题】:Advantage of computed properties (gettable ones only) vs. stored properties计算属性(仅限可获取的)与存储属性的优势
【发布时间】:2016-08-16 18:13:32
【问题描述】:

我想澄清一下我是否正确理解了以下概念。

假设我的目标是将String "Good morning, Mike" 存储到变量var sayGoodMorningToUser 中。

String由两个变量组成,即

var greeting = "Good morning, "
var username = "Mike"

如果我使用存储属性与计算属性有什么区别,换句话说:

var sayGoodMorningToUserStored = greeting + username

对比

var sayGoodMorningToUserComputed:String {
     return greeting + username
}

我看到这两种方法的唯一区别是任何人都可以轻松直接地更改 sayGoodMorningToUserStored 的值,例如通过写作

var sayGoodMorningToUserStored = "myNewChangedValue"

而变量 sayGoodMorningToUserComputed 不能直接修改,因为它不能简单地设置为新的字符串值:

var sayGoodMorningToUserComputed = "Hallo" //this would cause an error 

否则我无法理解为什么人们计算变量而不是简单地写

var sayGoodMorningToUserStored = greeting + username.

如果我理解正确,谁能解释一下?或者计算变量与存储变量相比还有其他优势吗?

我想将我的问题仅限于可获取变量,因为在这里讨论可设置变量会超出范围。

【问题讨论】:

  • 计算属性的目的是您声明一次,当username 更改时,计算的“greeting”属性将自动更新以反映这一点。因此,如果username 发生更改,您也不必记得去更新sayGoodMorningToUserStored。如果您在代码中的其他地方引用它,它将自动反映 username 的当前值,而不是 sayGoodMorningToUserStored 首次声明时的 username 原样。
  • 我现在能想到的主要区别在于协议和协议扩展。使用协议不能保持状态,因此计算值是最好的。
  • @Pisan 如果您觉得您的问题已得到满足,请评价将问题标记为已接受。

标签: swift properties


【解决方案1】:

您的示例中的不同之处在于:

var sayGoodMorningToUserStored = "myNewChangedValue" 

var sayGoodMorningToUserStored = greeting + username

在你的类初始化时设置,而这个:

var sayGoodMorningToUserComputed:String {
     return greeting + username
}

每次访问该属性时都会进行评估。

简单的例子是一个有firstNamelastName的类,但也想要fullName。使用普通属性,每次更新 firstNamelastName 时,您还必须更新 fullName 以便匹配。使用计算属性,每次访问 fullName 时,您都会获得最新信息。

【讨论】:

    【解决方案2】:

    计算属性

    var sayGoodMorningToUserComputed: String {
         return greeting + username
    }
    

    sayGoodMorningToUserComputed 就像一个函数。如果对greetingusername 进行了更改,则sayGoodMorningToUserComputed 将返回一个最新的结果,该结果将是当前值的串联。

    如果您想确保返回值是根据其依赖项的最新值(greetingusername)计算出来的,您可能需要使用它。

    如果两个依赖项都是final,那么编译器很可能会将这个计算属性优化为存储属性,因为它知道依赖项不能改变

    存储的属性

    var sayGoodMorningToUserStored = greeting + username
    

    sayGoodMorningToUserStored 只是一个变量,没有什么特别之处。但是,它只设置一次,每当初始化包含范围时。它计算一次,存储并保持不变,直到它被外部源覆盖。因此,如果 greetingusername 发生变化,则不会对 sayGoodMorningToUserStored 产生影响,因为它是根据旧值计算并存储的。

    如果您想通过缓存依赖关系不变的计算结果来提高性能,您可能会想要使用它。

    【讨论】:

      猜你喜欢
      • 2023-03-19
      • 2017-06-11
      • 2018-05-24
      • 2015-04-18
      • 2014-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-12
      相关资源
      最近更新 更多