在 Swift 中,方法是与特定类型相关联的函数。类、结构体和枚举都可以定义方法来实现它们所需的功能。本文将深入讨论 Swift 中的方法,包括实例方法、类型方法和可变方法。
实例方法
实例方法是与特定实例相关联的函数。它们被定义为类、结构体和枚举的成员。实例方法定义了要在该类型的每个实例上执行的任务。例如,你可能会定义一个 Person
类,其中包含一个名为 sayHello()
的方法,用于向其他人打招呼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Person {
var name: String
init(name: String) {
self.name = name
}
func sayHello() {
print("Hello, my name is \(name)")
}
}
let person = Person(name: "John")
person.sayHello()
// 输出:"Hello, my name is John"
在此示例中,Person
类定义了一个 sayHello()
方法。当 person
实例调用该方法时,它会打印一条问候语。
self 关键字
实例方法可以使用 self
关键字来引用当前实例。例如,如果你希望在 sayHello()
方法中引用实例的名称属性,则可以使用 self.name
:
1
2
3
func sayHello() {
print("Hello, my name is \(self.name)")
}
不过,在大多数情况下,你可以省略 self
关键字。编译器将自动推断出你正在引用当前实例。
在实例方法中修改值类型
默认情况下,值类型(如结构体和枚举)的属性不能在其实例方法中进行修改。但是,如果你需要修改实例的属性,则可以将方法标记为 mutating
:
1
2
3
4
5
6
7
8
9
10
11
12
13
struct Point {
var x = 0.0, y = 0.0
mutating func moveBy(x deltaX: Double, y deltaY: Double) {
x += deltaX
y += deltaY
}
}
var point = Point(x: 1.0, y: 1.0)
point.moveBy(x: 2.0, y: 3.0)
print("(\(point.x), \(point.y))")
// 输出:"(3.0, 4.0)"
在此示例中,Point
结构体定义了一个 moveBy(x:y:)
方法,并将其标记为 mutating
。该方法修改了结构体实例的 x
和 y
属性。
要调用 mutating
方法,你必须将结构体或枚举实例分配给变量。这是因为在 Swift 中,值类型的属性始终作为常量处理,除非它们所属的实例是可变的。
类型方法
类型方法是与类型本身相关联的函数。它们被定义为类、结构体和枚举的静态成员。类型方法定义了在没有任何实例的情况下执行的任务。例如,你可能会定义一个 Math
结构体,其中包含一个名为 abs(_:)
的方法,用于计算一个数字的绝对值:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct Math {
static func abs(_ x: Int) -> Int {
if x < 0 {
return -x
} else {
return x
}
}
}
let x = -5
let absX = Math.abs(x)
print(absX)
// 输出:"5"
在此示例中,Math
结构体定义了一个静态方法 abs(_:)
。要调用该方法,你不需要创建 Math
实例;只需直接通过类型名称调用即可。
类型方法中的 self 关键字
与实例方法类似,类型方法也可以使用 self
关键字来引用该类型本身。例如,如果你希望在 Math
结构体的类型方法中引用它本身,则可以使用 self
关键字:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
struct Math {
static func abs(_ x: Int) -> Int {
if x < 0 {
return -x
} else {
return x
}
}
static func max(_ x: Int, _ y: Int) -> Int {
return x > y ? x : y
}
static func min(_ x: Int, _ y: Int) -> Int {
return x < y ? x : y
}
static func random(in range: Range<Int>) -> Int {
let count = UInt32(range.upperBound - range.lowerBound)
return Int(arc4random_uniform(count)) + range.lowerBound
}
}
let x = Math.random(in: 1..<10)
print(x)
// 输出:随机的 1 到 9 之间的整数
在此示例中,Math
结构体定义了四个类型方法:abs(_:)
、max(_:_:)
、min(_:_:)
和 random(in:)
。这些方法不需要实例即可执行。
可变方法
可变方法是一种特殊类型的实例方法,允许修改它们所属的实例。它们通过将方法标记为 mutating
来进行定义。例如,你可能会定义一个名为 toggle()
的可变方法,用于切换布尔值:
1
2
3
4
5
6
7
8
9
10
extension Bool {
mutating func toggle() {
self = !self
}
}
var boolValue = true
boolValue.toggle()
print(boolValue)
// 输出:"false"
在此示例中,我们使用扩展为 Swift 中的布尔类型添加了一个 toggle()
方法,并将其标记为 mutating
。当我们调用该方法时,它会切换当前的布尔值。
在可变方法中给 self 赋新值
可变方法可以通过给 self
赋新值来修改它们所属的实例。例如,如果你想在 Point
结构体中添加一个名为 moveTo(x:y:)
的方法,该方法将点移动到指定位置,则可以这样编写可变方法:
1
2
3
4
5
6
7
8
9
10
11
12
struct Point {
var x = 0.0, y = 0.0
mutating func moveTo(x: Double, y: Double) {
self = Point(x: x, y: y)
}
}
var point = Point(x: 1.0, y: 1.0)
point.moveTo(x: 3.0, y: 4.0)
print("(\(point.x), \(point.y))")
// 输出:"(3.0, 4.0)"
在此示例中,Point
结构体定义了一个可变方法 moveTo(x:y:)
,该方法将点移动到指定位置。要执行此操作,该方法简单地创建一个新的 Point
实例并将其分配给 self
。