swift中struct和class的區(qū)別

Structure 和Class 的差別

相同之處

1.擁有自己的屬性(property)及方法(function)
2.可以自訂建構(gòu)子(initializer)

不同之處
  1. Structure無法繼承
  2. Structure擁有成員建構(gòu)子(Memberwise Initializer)
  3. Structure是Value Type , Class是Reference Type
  4. Structure不能直接修改內(nèi)部屬性,如果要修改必須加上mutating

大致意思就是說圆恤,雖然結(jié)構(gòu)體和枚舉可以定義自己的方法蚤霞,但是默認情況下茸苇,實例方法中是不可以修改值類型的屬性胁住。
舉個簡單的例子筹吐,假如定義一個點結(jié)構(gòu)體,該結(jié)構(gòu)體有一個修改點位置的實例方法:

struct Point {
  var x = 0, y = 0
  
  func moveXBy(x:Int,yBy y:Int) {
    self.x += x
    // Cannot invoke '+=' with an argument list of type '(Int, Int)'
    self.y += y
    // Cannot invoke '+=' with an argument list of type '(Int, Int)'
  }
}

編譯器拋出錯誤狮崩,說明確實不能在實例方法中修改屬性值蛛勉。

為了能夠在實例方法中修改屬性值,可以在方法定義前添加關(guān)鍵字 mutating

struct Point {
  var x = 0, y = 0
  mutating func moveXBy(x:Int,yBy y:Int) {
    self.x += x
    self.y += y
  }
}
var p = Point(x: 5, y: 5)
p.moveXBy(3, yBy: 3)

另外睦柴,在值類型的實例方法中诽凌,也可以直接修改self屬性值。

enum TriStateSwitch {
  case Off, Low, High
  mutating func next() {
    switch self {
    case Off:
      self = Low
    case Low:
      self = High
    case High:
      self = Off
    }
  }
}
var ovenLight = TriStateSwitch.Low
ovenLight.next()
// ovenLight is now equal to .High
ovenLight.next()
// ovenLight is now equal to .Off”

TriStateSwitch枚舉定義了一個三個狀態(tài)的開關(guān)坦敌,在next實例方法中動態(tài)改變self屬性的值侣诵。

當然,在引用類型中(即class)中的方法默認情況下就可以修改屬性值狱窘,不存在以上問題杜顺。

7. 值類型和引用類型的區(qū)別

由于 Swift 中的 struct 為值類型,class 為引用類型训柴,因此文中以這兩種類型為代表來具體闡述

stack & heap

內(nèi)存(RAM)中有兩個區(qū)域哑舒,棧區(qū)(stack)和堆區(qū)(heap)妇拯。在 Swift 中幻馁,值類型洗鸵,存放在棧區(qū);引用類型仗嗦,存放在堆區(qū)膘滨。

class RectClass {
    var height = 0.0
    var width = 0.0
}

struct RectStruct {
    var height = 0.0
    var width = 0.0
}

var rectCls = RectClass()
var rectStrct = RectStruct()

值類型(Value Type)

值類型,即每個實例保持一份數(shù)據(jù)拷貝稀拐。

在 Swift 中火邓,典型的有 structenum德撬,以及 tuple 都是值類型铲咨。而平時使用的 IntDouble蜓洪,Float纤勒,StringArray隆檀,Dictionary摇天,Set 其實都是用結(jié)構(gòu)體實現(xiàn)的,也是值類型恐仑。
Swift 中泉坐,值類型的賦值為深拷貝(Deep Copy),值語義(Value Semantics)即新對象和源對象是獨立的裳仆,當改變新對象的屬性腕让,源對象不會受到影響,反之同理鉴逞。
在 Swift 中,雙等號(== &!=)可以用來比較變量存儲的內(nèi)容是否一致,如果要讓我們的struct 類型支持該符號滑凉,則必須遵守 Equatable協(xié)議畅姊。

extension CoordinateStruct: Equatable {
    static func ==(left: CoordinateStruct, right: CoordinateStruct) -> Bool {
        return (left.x == right.x && left.y == right.y)
    }
}

if coordA != coordB {
    print("coordA != coordB")
}

引用類型(Reference Type)

引用類型若未,即所有實例共享一份數(shù)據(jù)拷貝倾鲫。

在 Swift 中萍嬉,class 和閉包是引用類型隙疚。引用類型的賦值是淺拷貝(Shallow Copy),引用語義(Reference Semantics)即新對象和源對象的變量名不同,但其引用(指向的內(nèi)存空間)是一樣的悼做,因此當使用新對象操作其內(nèi)部數(shù)據(jù)時贿堰,源對象的內(nèi)部數(shù)據(jù)也會受到影響。

class Dog {
    var height = 0.0
    var weight = 0.0
}

var dogA = Dog()
var dogB = dogA

dogA.height = 50.0
print("dogA.height -> \(dogA.height)")
print("dogB.height -> \(dogB.height)")

// dogA.height -> 50.0
// dogB.height -> 50.0

如果聲明一個引用類型的常量庶灿,那么就意味著該常量的引用不能改變(即不能被同類型變量賦值)纵搁,但指向的內(nèi)存中所存儲的變量是可以改變的腾誉。
在 Swift 中瘦癌,三等號(=== &!==)可以用來比較引用類型的引用(即指向的內(nèi)存地址)是否一致热押。也可以在遵守 Equatable 協(xié)議后桶癣,使用雙等號(==&!=)用來比較變量的內(nèi)容是否一致。

函數(shù)傳參

在 Swift 中尤慰,函數(shù)的參數(shù)默認為常量,即在函數(shù)體內(nèi)只能訪問參數(shù)匪煌,而不能修改參數(shù)值。具體來說:
1.值類型作為參數(shù)傳入時,函數(shù)體內(nèi)部不能修改其值
2.引用類型作為參數(shù)傳入時,函數(shù)體內(nèi)部不能修改其指向的內(nèi)存地址刀森,但是可以修改其內(nèi)部的變量值

值類型

當值類型的變量作為參數(shù)被傳入函數(shù)時埠偿,相當于創(chuàng)建了新的常量并初始化為傳入的變量值,該參數(shù)的作用域及生命周期僅存在于函數(shù)體內(nèi)榜晦。
當引用類型的變量作為參數(shù)被傳入函數(shù)時冠蒋,相當于創(chuàng)建了新的常量并初始化為傳入的變量引用,當函數(shù)體內(nèi)操作參數(shù)指向的數(shù)據(jù)乾胶,函數(shù)體外也受到了影響
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末浊服,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子胚吁,更是在濱河造成了極大的恐慌牙躺,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腕扶,死亡現(xiàn)場離奇詭異孽拷,居然都是意外死亡,警方通過查閱死者的電腦和手機半抱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門脓恕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來膜宋,“玉大人,你說我怎么就攤上這事炼幔∏锩#” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵乃秀,是天一觀的道長肛著。 經(jīng)常有香客問我,道長跺讯,這世上最難降的妖魔是什么枢贿? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮刀脏,結(jié)果婚禮上局荚,老公的妹妹穿的比我還像新娘。我一直安慰自己愈污,他們只是感情好耀态,可當我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著暂雹,像睡著了一般茫陆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上擎析,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天簿盅,我揣著相機與錄音,去河邊找鬼揍魂。 笑死桨醋,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的现斋。 我是一名探鬼主播喜最,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼庄蹋!你這毒婦竟也來了瞬内?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤限书,失蹤者是張志新(化名)和其女友劉穎虫蝶,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體倦西,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡能真,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片粉铐。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡疼约,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蝙泼,到底是詐尸還是另有隱情程剥,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布汤踏,位于F島的核電站织鲸,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏茎活。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一琢唾、第九天 我趴在偏房一處隱蔽的房頂上張望载荔。 院中可真熱鬧,春花似錦采桃、人聲如沸懒熙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽工扎。三九已至,卻和暖如春衔蹲,著一層夾襖步出監(jiān)牢的瞬間肢娘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工舆驶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留橱健,地道東北人。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓沙廉,卻偏偏與公主長得像拘荡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子撬陵,可洞房花燭夜當晚...
    茶點故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容