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 类型的属性 xy。还包含一个带参数的初始化器和一个计算与其他点的距离的方法。

结构体的实例化

结构体的实例化使用 varlet 关键字和结构体名称,在后面加上括号来完成。如果结构体中没有自定义初始化器,则可以使用默认成员初始化器来创建实例。

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 的标准库中得到了广泛应用。