是什么让 属性 成为 Swift 中的计算 属性

What makes a property a computed property in Swift

让我们从代码片段开始:

St Foo {
    var proA: Int = 0 { // needs initialization
        willSet {
            print("about to set proA to \(newValue) from \(proA)")
        }
        didSet {
            print("already set proA to \(proA) from \(oldValue)")
        }
    }

    var ProB: Int { // do not needs initialization 
        return 1
    }
}

let foo = Foo()
foo.proA = 23
print(foo.ProB)

下面是我个人对存储和计算的一些理解属性:

a:只有观察者(willSet 和 didSet)的 属性 不是计算的 属性,而是存储的 属性(例如 proA 属性 在上面的代码中)。

b: Computed 属性 必须没有初始化(见上面代码的注释)。

c: setter 有点等于 属性 观察者,属性 观察者只是 setter + 变异前后的观察者.

问题:

1. 我想知道是什么让 属性 成为计算的 属性?只要 属性 有一个 getter 和 return 它就是计算的 属性 是否正确?

2.我的理解(a, b & c)都正确吗?如果没有,请您指出。

3. 为什么不允许初始化一个computed 属性? (请参见下图)当我这样做时,编译器发出警告 Cannot call value of none-function type "int" 这个错误是什么意思?

非常感谢。

首先,这是关于变量,而不是属性任何变量都可以是计算变量。 属性 只是使用变量的一种方式。

我认为总的来说你犯了一个很大的错误,将一个存储变量与 setter 观察者并排放置在一个计算变量上。他们没有关系!

将计算变量想象成在您使用它时看起来和行为都像变量的东西——您获取并(可能)设置它——但实际上是一个函数(或一对函数). 这只是调用函数的一种紧凑方式。这是 全部

另一方面,带有观察者的存储变量只是一个也有一些观察者的存储变量。


好的,关于你的问题:

  1. I wonder what makes a property a computed property? Is is correct that as long as the property has a getter and return it is a computed property?

是的。它是一个计算变量,因为您使用使其成为计算变量的语法声明它(使用花括号)。

  1. Are all my understandings (a, b & c) correct? If not would be nice of you to point out

是的。我认为您的 "c" 很有见地:计算变量不需要 setter observer 因为它有(喘息!) setter!

  1. Why is it not allowed to initialize an computed property? (Please see the figure below) And when I do so the compiler gives out the warning Cannot call value of none-function type "int" What's the meaning of this error?

计算变量 "has" 一个值是没有意义的——它是计算出来的!这只是一些功能! — 所以给它分配一个 "initial" 值是没有意义的。

A stored 属性是一个属性,其中属性值与[=37=的实例一起存储] 或结构。该值可以更改,但 属性 也可以是常量。因此,存储的 属性 可以像这样简单:

var proA: Int
let proB: Int
var proC: Int = 0

计算属性 不存储值。因此,您不能为计算的 属性 赋值。一个 Computed 属性 应该有一个 getter 并且 return 是一个值。我是一个广义的术语,您可以将计算的 属性 视为 属性,return 是一个函数的值。

计算示例属性

var proA: Int {
    return proB * proC
}

关于您的问题:

  1. Computed 属性 因此是 属性 不存储值,并且包含对 return 'computed' 属性.
  2. 的值
  3. a 是正确的,b 计算属性不应该有初始化,c 如果你的意思是 willSet 和 didSet。是的,他们就像观察者,观察 属性 的值何时会发生变化,并且确实发生了变化
  4. 由于计算 属性 的值不会被存储并且永远不会被使用,因此编译器禁止它。

希望对您有所帮助。

  1. 我想知道是什么让 属性 成为计算的 属性?只要 属性 有一个 getter 和 return 它就是一个计算的 属性?
  2. 是正确的

If you define get { } inside the property declaration, it makes that property to a computed property. And it cannot have initial value as when you access the property, it will always call get{} function declared in property.

  1. 我的理解(a, b & c)都正确吗?如果没有,你会很高兴指出

    • 一个是正确的
    • b 是错误的。

    您不能为计算 属性 设置初始值。 因为正如我在问题 1 中解释的那样,当您需要访问 属性.

    时,它总是 get{} 的 return 结果
    • c : 50% 正确

    setter ,它也可以用来将 newValue 存储到另一个私有变量中,你可以做一些额外的 observing 逻辑。因此,要观察存储的 属性 上的值变化,您可以使用 willSetdidSet 您可以在 set{} 声明的计算 属性(具有 gettersetter)上定义 observing 逻辑。但 set {} 的主要目的是将值存储到另一个变量或例如 UserDefaults.

  2. 为什么不允许初始化计算属性? (请参见下图)当我这样做时,编译器发出警告 Cannot call value of none-function type "int" What's the meaning of this error?

    同样的回答

    你的代码让编译器感到困惑 当您在 属性 on 声明中设置初始值时,编译器会尝试将其理解为 stored 属性。但是您还为这个 属性 定义了 get{},这意味着它是计算出来的 属性 并且当您访问 属性 时应该总是 return 22 .所以你应该删除两者之一。

一个。是的,只有观察者的 属性 是存储的 属性 而不是计算的 property.Beacuase 属性 观察者跟踪 属性 的值,其值先前已初始化并且它是现在改变了,这是一个存储 属性。它不适用于计算 属性,因为它没有预定义值

b。 computed 属性 是一个 属性 ,其值取决于其他变量,我们应该只将那些属性声明为 computed 属性 ,需要使用另一个变量的值来计算,因此它的值不能是提前初始化。 例如- 如果我们有 2 个变量 a 和 b。我们需要它们的加法值,所以使用了一个名为 'sum' 的变量,然后 sum 将被声明为一个计算的 属性 & 它的 get{} 块将 return (a+b) 这就是总和a & b & 的值 variable.Then 在这种情况下我们不能初始化 属性 'sum' 提前,因为它将使用 a & b 计算。

c。 Setter 不是观察者,它设置另一个变量的值或执行与其他变量相关的一些操作,而 属性 观察者跟踪其关联变量本身的值的变化。例如如 b 点所述,对变量 'sum' 使用 属性 观察器是没有意义的。