Swift 结构体
Swift 结构体
Swift 中的结构体是一种传值类型,它可以封装相同或不同类型的变量、常量和函数。结构体同样可以实现协议。结构体与类有很多相似之处,但是它们也有自己的特性。
结构体定义
结构体的定义使用 struct
关键字,结构体的名称要遵循大驼峰命名法。结构体中可以定义属性、方法和初始化器等。
struct Point {
var x: Int
var y: Int
init(x: Int, y: Int) {
self.x = x
self.y = y
}
func distance(to other: Point) -> Double {
let xDist = Double(x - other.x)
let yDist = Double(y - other.y)
return sqrt(xDist * xDist + yDist * yDist)
}
}
上面的代码定义了一个名为 Point
的结构体,封装了两个 Int
类型的属性 x
和 y
。还包含一个带参数的初始化器和一个计算与其他点的距离的方法。
结构体的实例化
结构体的实例化使用 var
或 let
关键字和结构体名称,在后面加上括号来完成。如果结构体中没有自定义初始化器,则可以使用默认成员初始化器来创建实例。
var origin = Point(x: 0, y: 0)
let destination = Point(x: 10, y: 10)
上述代码创建了两个 Point
类型的实例,一个名为 origin
,另一个名为 destination
。由于 origin
被声明为变量,因此它的属性可以改变。而 destination
被声明为常量,因此它的属性不能改变。
结构体的属性访问
结构体的属性可以使用点语法来访问和修改。
print(origin.x) // 输出 0
origin.x = 5
print(origin.x) // 输出 5
结构体的成员初始化器
结构体默认提供成员初始化器,又称为逐一成员初始化器。这个成员初始化器接受结构体中定义的每个属性作为参数,并使用它们来初始化结构体的实例。
let p = Point(x: 15, y: 20)
print(p.x) // 输出 15
print(p.y) // 输出 20
由于我们已经自定义了 Point
的初始化器,因此默认的初始化器就不再可用。
结构体的值传递
结构体是值类型,这意味着在传递结构体实例时,将传递该实例的副本,而不是引用到原始实例。这确保了每个实例都是独立的,从而避免了副作用和其他副作用。
struct Color {
var red: Double
var green: Double
var blue: Double
}
func darken(_ color: Color) -> Color {
var darkColor = color
darkColor.red *= 0.8
darkColor.green *= 0.8
darkColor.blue *= 0.8
return darkColor
}
var c1 = Color(red: 0.5, green: 0.7, blue: 1.0)
var darkC1 = darken(c1)
print(c1.red) // 输出 0.5
print(darkC1.red) // 输出 0.4
上述代码中,函数 darken(_:)
接受 Color
类型的参数并返回一个 Color
类型的值。在此过程中,传入的 color
参数的值被复制到新变量 darkColor
中。在函数内部,对 darkColor
进行的任何更改都不会影响原始 c1
变量的值。
结构体和类的比较
- 结构体是值类型,类是引用类型。值类型内存生命周期取决于它们的使用方式,而引用类型生命周期取决于它们的引用方式。
- 结构体无法继承,但可以遵循协议。
- 结构体的实例化速度通常比类的实例化速度更快,但对于复杂数据结构,类是更好的选择。
- 结构体通常用于轻量级的数据模型,如图形、颜色和值类型,而类通常用于表示更复杂的实体,如网络请求或视图控制器。
总结
Swift 语言提供了结构体作为一种轻量级的传值类型,它可以封装数据和行为。与类相比,结构体具有更好的性能和内存管理,并在许多场景下更加适用。但是它们也有它们的限制,例如无法继承。结构体在 Swift 中扮演着重要的角色,Swift 核心是建立在值类型上的,并且这种思想在 Swift 的标准库中得到了广泛应用。