swift 結構體


在OC概念中經常提到的是類,但是在swift底層聲明中已經大部分使用了struct結構體,下面我們就來講解一下swift中的結構體.

 

一、類與結構體的區別

  1. 語義
  • 類: 引用類型(引用語義),需要自己管理引用計數,引用值的變化
  • 結構體:可以被直接持有及訪問,不會被引用,但是會被復制.也就是說,結構體的持有者是唯一的

  拓展:

    byte,short,int,long,float,double,decimal,char,bool 和 struct 統稱為值類型。

    string,類等皆為引用類型。

    值類型變量聲明后,不管是否已經賦值,編譯器為其分配內存。此時該值存儲於棧上;int i=10;執行之前為默認一個值0。

    引用類型定義時在棧上開辟一個空間用來存放其在堆上的地址,當賦值或者實例化時候就會在堆上開辟一個空間,然后把堆中的地址存放在棧中,這時候棧就存放了其地址。

 

  2.  內存管理方式

  • 類: 類的實例只能通過引用來間接地訪問,類能有很多個持有者
  • 結構體: 可以被直接持有及訪問,不會被引用,但是被復制,也就是說,結構體的持有者是唯一的

 

  3.  共享代碼

  • 類: 通過繼承來共享代碼
  • 結構體(以及枚舉): 不能被繼承,想要在不同的結構體或者枚舉之間共享代碼,我們需要使用不同的技術,比如像是組合、泛型以及協議拓展

 

 

二、結構體

結構體為值類型

值類型意味着一個值變量被復制時,這個值本身也會被復制,而不只限於對這個值的引用的復制.

let a = 12
let b = a 
a += 1 
print (a) // 13
print (b) // 12
b的值沒有根據a的值進行改變

而在swift中結構體的功能也被擴大化了,基本擁有了和類差不多的功能:

  • 定義屬性
  • 定義方法
  • 定義getter和setter
  • 可以定義初始化器來設置初始狀態
  • 實現擴展的功能
  • 遵循協議,並實現協議的方法
  • 結構總是被復制,並且不使用引用計數

類具有結構不具備的附加功能:

  • 繼承允許一個類繼承另一個類的特征
  • 類型轉換使你能夠在運行時檢查和解釋類實例的類型
  • 初始化器使一個類的實例能夠釋放它所分配的任何資源
  • 引用計數允許多個引用到一個類實例

 

1.定義結構體和類,並且為其添加變量和方法

struct Resolution {
    var width = 0
    var height = 0
    
    func resolutionFun() {
        print("method of struct Resolution")
    }
}

class VideoMode {
    var resolution = Resolution()
    var interlaced = false
    var frameRate = 0.0
    var name: String?
    
    func VideoMode() {
        print("method of class VideoMode")
    }
}

 

2.類和結構體的初始化

let object Name = Class Name()
let  variable Name = Struct Name()


let someResolution = Resolution()
let someVideoMode = VideoMode()

訪問屬性

Swift中訪問屬性使用的是鏈式結構,訪問屬性的時候使用 .

print("The width of someResolution is \(someResolution.width)")
print("The width of someVideoMode is \(someVideoMode.resolution.width)")

結構體的初始化

struct Resolution {
    var width = 0
    var height = 0
}

let resolution = Resolution(width:100,height:120)
print("width:\(resolution.width),height:\(resolution.height)")
結果:
width:100,height:120

首先要知道初始化器是系統本身的方法,我們只能去重寫或者重載它

重載就是將父類已有的方法通過擴充參數的形式重新定義一遍。

class VideoMode {
    var _name: String
    
    init(){
        _name = "Jin"
    }
    
    init(name:String){
        _name = name;
    }
    
}

let videoModeNormal = VideoMode()
print("name:\(videoModeNormal._name)")
let videoModeCustom = VideoMode(name: "Jack")
print("name:\(videoModeCustom._name)")
結果:
name:Jin
name:Jack

當然,struct的初始化方法也是可以這樣實現的:

struct Resolution {
    var width: Double
    
    init(){
        width = 100
    }
    
    init(width:Double){
        self.width = width;
    }
    
}

let resolutionNormal = Resolution()
print("width:\(resolutionNormal.width)")
let resolutionCustom = Resolution(width: 120)
print("width:\(resolutionCustom.width)")
結果:
width:100.0
width:120.0

 

類和結構體的選擇

 結構體實例通過值傳遞,類實例通過引用傳遞.這意味兩者通過不同的任務,當你在考慮一個項目數據構造和功能的時候,你需要決定每個數據構造是定義成類還是結構體.

當符合一條或多條以下條件時,請考慮構建結構體:

  • 結構體的主要目的是用來封裝少量相關的簡單數據值
  • 有理由預計一個結構體實例在賦值或傳遞時,封裝的數據將會被拷貝而不是被引用
  • 任何在結構體中儲存的值類型屬性,也會被拷貝,而不是被引用
  • 結構體不需要去繼承另一個已存在類型的屬性或者行為

為什么Swift中推薦使用Struct?

Swift 里更推薦使用值類型變量(struct)而不是引用類型(class)的變量,Swift中許多常見的數據類型,字符串,集合類型以及結構體和枚舉都是值類型而非引用類型,值類型的變量在賦值時會自動進行一次低消耗的值拷貝,對比對象的copy要更加高效而且不存在線程安全的問題.

 

上面就是Swift中的Struct結構體.希望對大家有所幫助!!!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM