Swift Struct 结构体

前言

  • Swift 语言有两种基本的数据类型,即类(class)和结构体(struct),class 这样的概念你们不会陌生,而 struct 也并非什么新的概念,在 Objective-C 和 C 中也有 struct,不过 Swift 将 struct 提高到一个更高更重要的层次,甚至 Swift Foundation 框架的 SDK,诸如 String,Array,Dictionary 都是基于 struct 实现的。swift

  • 结构体是由一系列具备相同类型或不一样类型的数据构成的数据集合。app

  • 和 class 同样,struct 也能够定义属性和方法,一样 struct 也要求完整初始化,即保证初始化过程当中每个 non-optional 属性要赋予明确的初始值。框架

  • 结构体是值类型,而且只有在赋予变量或常量,或者被函数调用时才被赋值。函数

一、结构体的建立

  • 结构体基本结构ui

    struct 结构体名 {
    
        var 或 let 字段名 = 初始化值
        var 或 let 字段名: 类型
    }
    struct Student {
    
        var age = 0
    }
    
    var stu = Student()
    
    /// struct      结构体关键字
    /// Student     结构体名称
    
    /// student()   建立一个结构体变量

1.1 标准定义

  • 结构体的定义线程

    • 定义结构体字段时能够直接定义一个字段名,而且给字段名赋初始值。或者只定义一个字段名,不赋初始值,可是不赋初始值的字段在建立结构体变量时必须赋初始值。指针

      struct Student {                              
      
          var name: String                           // 只定义一个字段名,不赋初始值
          var age = 0                                // 定义一个字段名,而且给字段名赋初始值
      }
  • 结构体的使用code

    • 建立结构体变量时,结构体的字段都必须都有初始值,不然会报错。对象

      let s = Student(name: "appple", age: 8)        // 建立结构体变量时初始化结构体的字段
      
      print("\(s.name), \(s.age)")                   // 结构体类型变量值的调用

1.2 基本定义

  • 结构体的定义继承

    • 每一个字段名都赋初始值。

      struct BookInfo {                               
      
          var id: Int = 0                            // 每一个字段名都赋初始值
          var name: String = "Default"
          var author: String = "Default"
          var rootType: String = "Default"
      }
  • 结构体的使用

    • 建立结构体变量时,结构体的字段都必须都有初始值,不然会报错。

      let book = BookInfo()                          // 建立结构体变量时再也不须要初始化结构体的字段
      
      print("\(book.id), \(book.name), \(book.author), \(book.rootType)")     // 结构体类型变量值的调用

二、结构体的方法

2.1 定义枚举的方法

  • 枚举方法的定义

    struct markStruct1 {
    
        var mark1: Int = 0
        var mark2: Int = 0
        var mark3: Int = 0
    
        func sum(a: Int) -> Int {                                // 定义方法
    
            return (self.mark1 + self.mark2 + self.mark3) * a
        }
    }
  • 枚举方法的使用

    let mark1 = markStruct1(mark1: 11, mark2: 22, mark3: 33)
    
    print(mark1.sum(a: 2))                                       // print 132

2.2 自定义构造方法

  • 与 class 的初始化方法不一样点

    • struct 的 init 并无便利初始化(convenience init)方法。
    • 由于 struct 没有继承,因此 struct 的 init 也不须要 required 关键字。
  • 这样对比,struct 的初始化方法比起 class 的初始化方法来讲要简单的多,由于 struct 只有指定初始化,struct 只须要保证指定初始化过程当中每一个非可选属性都赋值,没有复杂的初始化规则和规范,struct 相比于 class 也显得更加简单,更有亲和力。

  • 一旦咱们自定义了初始化器,系统自动的初始化器就不起做用了,若是还须要使用到系统提供的初始化器,在咱们自定义初始化器后就必须显式的定义出来。

  • 可失败构造方法

    struct markStruct2 {
    
        var mark1: Int
        var mark2: Int
        var mark3: Int
    
        init?(mark1: Int, mark2: Int, mark3: Int) {              // 可失败(failable)的构造方法
    
            self.mark1 = mark1
            self.mark2 = mark2
            self.mark3 = mark3
        }
    }
  • 普通构造方法

    struct markStruct3 {
    
        var mark1: Int
        var mark2: Int
        var mark3: Int
    
        init(mark1: Int, mark2: Int, mark3: Int) {               // 普通的构造方法
    
            self.mark1 = mark1
            self.mark2 = mark2
            self.mark3 = mark3
        }
    }
  • 使用

    let mark2 = markStruct2(mark1: 11, mark2: 22, mark3: 33)
    print("\(mark2?.mark1 ?? 0), \(mark2?.mark2 ?? 0), \(mark2?.mark3 ?? 0)")   // print 11, 22, 33
    
    let mark3 = markStruct3(mark1: 11, mark2: 22, mark3: 33)
    print("\(mark3.mark1), \(mark3.mark2), \(mark3.mark3)")                     // print 11, 22, 33

三、Swift 中枚举、结构体和类的比较

3.1 在 Swift 中类型引用和值引用的区别

  • 对于类型引用(class reference),将变量 a 赋值给变量 b,即 b = a,这样的赋值语句仅仅将 b 的指针与 a 的指针同样,指向同一块内存区域,此时改变 b 的值,a 也会跟着改变;

  • 对于值引用(value reference),赋值语句 b = a 处理的过程是开辟一个新的内存 b,将 a 变量的内容拷贝后存放到内存 b,这时 ab 彻底没有关系的两个变量,对 b 的改变不会影响到 a,反之亦然。

  • 在 Objective-C 时代,咱们对类型引用和值引用就有了必定的了解,例如在 Objective-C 中经常使用的 NSArray, NSDictionary, NSString, UIKit 等都是类型引用;而 NSInteger, CGFloat, CGRect 等则是值引用。

  • 显然,在 Objective-C 中,引用类型占据了很大的比重,如今使用 Swift 开发应用程序,开发者须要转变观念,由于 struct 在 Swift 变得愈来愈重要,观念的转变不只在于多使用 struct,还要求开发者理解 struct 的原理,优势及缺点。

3.2 枚举、结构体、类的共同点

  • 定义属性用于存储值,枚举只能定义计算属性
  • 定义方法以提供功能
  • 定义下标,以便用下标语法来访问它们的值
  • 定义初始化程序,以建立它们的初始状态
  • 支持扩展增长功能,来扩展它们的默认实现
  • 能够遵循协议,来完成特定标准功能

3.3 枚举、结构体、类的区别

  • 类是引用类型,而枚举和结构体是值类型
  • 类有继承功能,而枚举和结构体没有继承的功能

3.4 类特有的功能

  • 继承
  • 容许类型转换
  • 析构方法释放资源
  • 引用计数

3.5 该如何选择

  • 关于在新建一个类型时如何选择究竟是使用值类型仍是引用类型的问题其实在理解了二者之间的区别后是很是简单的,在这苹果官方已经作出了很是明确的指示

    • 当你使用 Cocoa 框架的时候,不少 API 都要经过 NSObject 的子类使用,因此这时候必需要用到引用类型 class。
    • 在其余状况下,有下面几个准则。
  • 1)何时该用值类型

    • 要用 == 运算符来比较实例的数据时
    • 你但愿那个实例的拷贝能保持独立的状态时
    • 数据会被多个线程使用时
  • 2)何时该用引用类型(class)

    • 要用 == 运算符来比较实例身份的时候
    • 你但愿有建立一个共享的、可变对象的时候
相关文章
相关标签/搜索