11. Swift 枚举结构体类的区别.png

结构体 枚举
构造器 原始值类型的枚举,
析构器
属性 可以定义计算属性
属性观察器
方法
下标脚本
继承
类型转换
扩展
协议
访问控制

构造器

只有当所有存储属性的初始值被确定后,对象的内存才会被完全初始化。

  1. class MyClass {
  2. var property1: Double
  3. var property2: String
  4. var property3: Int = 0
  5. var property4: Int?
  6. let property5 = 0
  7. /**
  8. 如果没有给 所有未赋初值的存储属性 定义构造器,
  9. 那么像 property1、property2,编译器都会提示让你给这些属性赋初值。
  10. 所以要么给它们赋初值、要么给它们定义对应的构造器。
  11. */
  12. init(property1: Double, property2: String) {
  13. self.property1 = property1
  14. self.property2 = property2
  15. }
  16. }

可变方法

在枚举、结构体的方法中,包括扩展、协议,如果直接修改 self 或其属性的值,编译器会报错:Cannot assign to property: ‘self’ is immutable,可以使用 mutating 修饰该方法。

  1. enum Direction {
  2. case Left
  3. case Right
  4. mutating func next() {
  5. switch self {
  6. case .Left:
  7. self = .Right
  8. case .Right:
  9. self = .Left
  10. }
  11. }
  12. }
  1. struct MyStruct {
  2. var property: String = ""
  3. mutating func test() {
  4. property = ""
  5. }
  6. }
  1. extension Int {
  2. mutating func square() { // 平方
  3. self = self * self
  4. }
  5. }
  6. var a = 10
  7. a.square()
  8. print(a) // 100

类型嵌套

Swift 中的类、结构体和枚举可以进行嵌套。优点是支持访问它外部的成员(包括方法、属性和其他嵌套类型),嵌套可以有多个层次。

  1. class Employee {
  2. var name = ""
  3. var no = 0
  4. var job = ""
  5. var day = WeekDays.Friday
  6. var dept = Department()
  7. struct Department {
  8. var no = 10
  9. var name = "Sales"
  10. }
  11. enum WeekDays{
  12. case Monday,Tuesday,Wednesday,Thursday,Friday
  13. struct Day {
  14. static var message = "Today is ..."
  15. }
  16. }
  17. }
  18. let employee = Employee()
  19. print(employee.day)
  20. print(employee.dept.name)
  21. print(Employee.WeekDays.Day.message)

协议

Swift 为协议提供默认的方法实现

  1. protocol MyProtocol {
  2. var property: String { get }
  3. func method()
  4. }
  5. extension MyProtocol {
  6. // 协议默认的方法实现
  7. func method() {
  8. // self 指遵循该协议,所生成的实例
  9. print("[Default Implement]: \(self) \(self.property)")
  10. }
  11. }
  12. class MyClass: MyProtocol {
  13. var property: String = "my-property"
  14. }
  15. let clz = MyClass()
  16. clz.method() // [Default Implement]: swift_demo.MyClass my-property
  17. print(type(of: MyClass.self)) // MyClass.Type
  18. print(type(of: clz.self)) // MyClass

选择结构体还是类

在比较类和结构体之间的区别之前,先了解两个概念,引用类型和值类型:

引用类型

引用类型在被赋予到一个变量、常量或者被传递到一个函数时,其值不会被拷贝。因此,引用的是已存在的实例本身而不是其拷贝

值类型

它们的实例,以及实例中所包含的任何值类型属性,在代码中传递的时候都会被复制,也就是值拷贝

类和结构体的本质区别:
• 类是引用类型,实例是通过引用传递
• 结构体是值类型,实例是通过值传递

考虑在一个或多个条件适用的情况下创建一个结构体:

  1. 结构体的主要目的是封装一些相对简单的数据值。
  2. 当合理的分配或传递该结构的实例时,封装的值将被复制,而不是被引用。
  3. 结构中存储的任何属性都是值类型,它也可以被复制,而不是被引用。
  4. 结构体不需要从另一个现有类型继承属性或行为。

优秀的结构体例子包括:
几何形状的大小,可能是封装了宽度属性和高度属性,两者都是 Double 类型。

在 Swift 中,许多基本的数据类型,如字符串、数组和字典都是作为结构体实现的。这意味着当将字符串、数组和字典等数据分配给新的常量或变量时,或者当它们被传递给函数或方法时,就会复制这些数据。

这种行为与 Foundation 库不同:NSString、NSArray 和 NSDictionary 都是作为类实现的,而不是结构。Foundation 中的字符串、数组和字典总是被分配和传递,作为对现有实例的引用,而不是作为副本。

备注:[选择结构体还是类]