
| 类 | 结构体 | 枚举 |
|---|---|---|
| 构造器 | ✔ | 原始值类型的枚举, |
| 析构器 | ✗ | ✗ |
| 属性 | ✔ | 可以定义计算属性 |
| 属性观察器 | ✔ | ✗ |
| 方法 | ✔ | ✔ |
| 下标脚本 | ✔ | ✔ |
| 继承 | ✗ | ✗ |
| 类型转换 | ✗ | ✗ |
| 扩展 | ✔ | ✔ |
| 协议 | ✔ | ✔ |
| 访问控制 | ✔ | ✔ |
构造器
只有当所有存储属性的初始值被确定后,对象的内存才会被完全初始化。
class MyClass {var property1: Doublevar property2: Stringvar property3: Int = 0var property4: Int?let property5 = 0/**如果没有给 所有未赋初值的存储属性 定义构造器,那么像 property1、property2,编译器都会提示让你给这些属性赋初值。所以要么给它们赋初值、要么给它们定义对应的构造器。*/init(property1: Double, property2: String) {self.property1 = property1self.property2 = property2}}
可变方法
在枚举、结构体的方法中,包括扩展、协议,如果直接修改 self 或其属性的值,编译器会报错:Cannot assign to property: ‘self’ is immutable,可以使用 mutating 修饰该方法。
enum Direction {case Leftcase Rightmutating func next() {switch self {case .Left:self = .Rightcase .Right:self = .Left}}}
struct MyStruct {var property: String = ""mutating func test() {property = ""}}
extension Int {mutating func square() { // 平方self = self * self}}var a = 10a.square()print(a) // 100
类型嵌套
Swift 中的类、结构体和枚举可以进行嵌套。优点是支持访问它外部的成员(包括方法、属性和其他嵌套类型),嵌套可以有多个层次。
class Employee {var name = ""var no = 0var job = ""var day = WeekDays.Fridayvar dept = Department()struct Department {var no = 10var name = "Sales"}enum WeekDays{case Monday,Tuesday,Wednesday,Thursday,Fridaystruct Day {static var message = "Today is ..."}}}let employee = Employee()print(employee.day)print(employee.dept.name)print(Employee.WeekDays.Day.message)
协议
Swift 为协议提供默认的方法实现
protocol MyProtocol {var property: String { get }func method()}extension MyProtocol {// 协议默认的方法实现func method() {// self 指遵循该协议,所生成的实例print("[Default Implement]: \(self) \(self.property)")}}class MyClass: MyProtocol {var property: String = "my-property"}let clz = MyClass()clz.method() // [Default Implement]: swift_demo.MyClass my-propertyprint(type(of: MyClass.self)) // MyClass.Typeprint(type(of: clz.self)) // MyClass
选择结构体还是类
在比较类和结构体之间的区别之前,先了解两个概念,引用类型和值类型:
引用类型
引用类型在被赋予到一个变量、常量或者被传递到一个函数时,其值不会被拷贝。因此,引用的是已存在的实例本身而不是其拷贝
值类型
它们的实例,以及实例中所包含的任何值类型属性,在代码中传递的时候都会被复制,也就是值拷贝
类和结构体的本质区别:
• 类是引用类型,实例是通过引用传递
• 结构体是值类型,实例是通过值传递
考虑在一个或多个条件适用的情况下创建一个结构体:
- 结构体的主要目的是封装一些相对简单的数据值。
- 当合理的分配或传递该结构的实例时,封装的值将被复制,而不是被引用。
- 结构中存储的任何属性都是值类型,它也可以被复制,而不是被引用。
- 结构体不需要从另一个现有类型继承属性或行为。
优秀的结构体例子包括:
几何形状的大小,可能是封装了宽度属性和高度属性,两者都是 Double 类型。
在 Swift 中,许多基本的数据类型,如字符串、数组和字典都是作为结构体实现的。这意味着当将字符串、数组和字典等数据分配给新的常量或变量时,或者当它们被传递给函数或方法时,就会复制这些数据。
这种行为与 Foundation 库不同:NSString、NSArray 和 NSDictionary 都是作为类实现的,而不是结构。Foundation 中的字符串、数组和字典总是被分配和传递,作为对现有实例的引用,而不是作为副本。
备注:[选择结构体还是类]
