Menu
CoddyTech

计算属性

本课属于 Coddy Swift 学习旅程的“面向对象编程”单元。第 12 课,共 57 课。

存储属性保存一个值。计算属性不存储值:每次读取时都会运行代码,并返回根据其他属性计算出的值:

struct Rectangle {
    var width: Double
    var height: Double

    var area: Double {
        width * height
    }
}

var r = Rectangle(width: 3, height: 4)
print(r.area)
r.width = 10
print(r.area)

输出:

12.0
40.0

由于每次读取时都会重新计算值,计算属性永远不会过期。读取计算属性的方式与读取存储属性相同,不需要括号:

struct Person {
    var first: String
    var last: String

    var fullName: String {
        "\(first) \(last)"
    }
}

var p = Person(first: "Ada", last: "Byron")
p.last = "Lovelace"
print(p.fullName)

输出:

Ada Lovelace

计算属性也可以有setter。set 会接收 newValue 作为新值,并更新它所依赖的存储属性:

struct Temperature {
    var celsius: Double

    var fahrenheit: Double {
        get { celsius * 9 / 5 + 32 }
        set { celsius = (newValue - 32) * 5 / 9 }
    }
}

var t = Temperature(celsius: 100)
print(t.fahrenheit)
t.fahrenheit = 32
print(t.celsius)

输出:

212.0
0.0

如果某个值可以根据其他值推导出来,而且计算成本低,就使用计算属性。如果计算需要参数或成本较高,就使用方法:

struct Order {
    var items: [Int]
    var total: Int { items.reduce(0, +) }           // 属性:不需要参数
    func total(withTax rate: Int) -> Int {           // 方法:需要一个参数
        total + total * rate / 100
    }
}
challenge icon

挑战

简单

为结构体 Circle 补充存储属性 radius 和三个只读计算属性:diameter(半径的两倍)、area(π r²,使用 Double.pi)以及 label。label 会返回 r=2.0 d=4.0 a=12.57,其中面积使用 String(format: "%.2f", area) 四舍五入到小数点后两位。

提供的代码会读取每行一个半径,创建一个 Circle 并打印 label。然后,它会将最后一个圆的半径加倍,再次打印它的 label,因此这些值必须随半径变化。

你的代码要写在 Circle.swift 中。main.swift 包含提供的输入/输出代码,不能编辑。

亲手试试

import Foundation

// 提供的输入输出代码:保持原样。
var input: [String] = []
while let line = readLine() { input.append(line) }
var last = Circle(radius: 0)
for line in input {
    last = Circle(radius: Double(line)!)
    print(last.label)
}
last.radius *= 2
print(last.label)
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: Swift 在线编辑器