Swift 中的类和结构体

Posted by Abin's blog on October 11, 2016

Swift 中的结构体的能力被大大加强,不仅可以拥有属性,还以有方法、构造函数、甚至是扩展和遵守协议。这样的结构体和类有很多相同点:

  • 属性:存储数据
  • 方法:提供一些功能
  • 下标:可以使用下标语法
  • 构造器:生成初始化值
  • 扩展:增加功能
  • 协议:提供某种通用功能

当然,类和结构体也有很多不同的地方,类还有许多独有的附加功能:

  • 继承:一个类可以继承另一个类的特征
  • 类型转换:运行时检查和解释一个类实例的类型
  • 析构器:一个类实例释放任何其所被分配的资源
  • 引用计数:对一个类的多次引用

结构体会提供一个默认的构造函数,这个构造函数是结构体所有的属性分别作为参数来构建:

struct MyPoint {
    var x = 0
    var y = 0
}
let point:MyPoint = MyPoint(x: 1, y: 2)

结构体和枚举都是值类型,值类型在赋值(给变量或者常量)和传递(作为参数给一个函数)的时候都会被拷贝,值类型实例的值属性也会被拷贝。 Swift 中的整型、浮点型、布尔型、字符串、字典、数组都是值类型,底层都是由结构体来实现的。

类是引用类型,引用类型在赋值和传递的时候,内容并不会被拷贝。因此赋值的实例和被赋值的实例其实是一份内容,内容在内存中也是一份。

值类型和引用类型的区别在于,值类型在赋值和传递的时候是深拷贝,而引用类型是浅拷贝。 深拷贝就是把内存地址中存放的内容也拷贝一份内存中的内容就会有两份;而浅拷贝只是拷贝了内存的地址,内存中的内容还是只有一份。

值和引用类型的区别

但需要注意的是,在 Swift 中,并不是值类型一旦被赋值和传递的时候就会被拷贝一份,只有当需要的时候,比如被赋值的实例去改变内容的时候才会真正的去拷贝。

那么,我们到底如何选择结构体或者类呢?如果你只是用来做以下功能是可以选择结构体:

  • 只是用来封装一些相关的数据
  • 这些数据被赋值或者传递的时候会被拷贝一份
  • 不需要被继承

比如 CGPointCGRectCGSize等都是结构体。