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)

    • 要用 == 運算符來比較實例身份的時候
    • 你但願有建立一個共享的、可變對象的時候
相關文章
相關標籤/搜索