Menu
CoddyTech

值语义

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

结构体是值类型:将结构体赋值给另一个变量时,会复制它。修改副本不会影响原始结构体,这与类不同:

struct Point {
    var x: Int
}

var a = Point(x: 1)
var b = a
b.x = 99
print(a.x)
print(b.x)

输出:

1
99

用类进行同样的比较,可以看出其中的区别:两个变量都引用同一个对象。

class PointRef {
    var x: Int
    init(x: Int) { self.x = x }
}

let a = PointRef(x: 1)
let b = a
b.x = 99
print(a.x)

输出:

99

将结构体传递给函数时,也会传递一份副本。参数是常量,因此要返回修改后的版本,函数会创建一份局部副本并将其返回:

struct Point {
    var x: Int
}

func shifted(_ p: Point, by dx: Int) -> Point {
    var copy = p
    copy.x += dx
    return copy
}

let start = Point(x: 1)
let moved = shifted(start, by: 4)
print(start.x)
print(moved.x)

输出:

1
5

结构体数组存储的是相互独立的值。通过索引修改一个元素,只会改变该元素;复制数组时,会复制其中的所有值:

struct Score {
    var points: Int
}

var round1 = [Score(points: 1), Score(points: 2)]
var round2 = round1
round2[0].points = 50
print(round1[0].points)
print(round2[0].points)

输出:

1
50
challenge icon

挑战

简单

完成 tryDiscount(_:percent:)。它接收一个 Price 结构体,并返回一份折扣后的副本:按百分比减少厘,结果向下取整。提供的代码会打印原价和折后价,因此原值必须保持不变。

提供的代码会读取以厘为单位的价格,以及每行一个百分比,并为每个百分比打印 was 1000, now 900。

你的代码写在 Price.swift 和 Functions.swift 中。main.swift 中包含提供的输入和输出代码,不能编辑。

亲手试试

// 提供的输入/输出代码:保持原样
var input: [String] = []
while let line = readLine() { input.append(line) }
let original = Price(cents: Int(input[0])!)
for line in input.dropFirst() {
    let cheaper = tryDiscount(original, percent: Int(line)!)
    print("was \(original.cents), now \(cheaper.cents)")
}
quiz icon自我测试

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

面向对象编程中的所有课

自己练习: Swift 在线编辑器