Swift 中的結(jié)構(gòu)體

在面向過(guò)程的編程語(yǔ)言(如C語(yǔ)言)中,結(jié)構(gòu)體用得比較多押框,但是面向?qū)ο笾蟛沓瘢缭贑++和OC中,結(jié)構(gòu)體已經(jīng)很少使用了橡伞。這是因?yàn)榻Y(jié)構(gòu)體能夠做的事情盒揉,類(lèi)完全可以取而代之。
而Swift語(yǔ)言卻非常重視結(jié)構(gòu)體兑徘,把結(jié)構(gòu)體作為實(shí)現(xiàn)面向?qū)ο蟮闹匾侄胃沼wift中的結(jié)構(gòu)體與C++和OC中的結(jié)構(gòu)體有很大的差別,C++和OC中的結(jié)構(gòu)體只能定義一組相關(guān)的成員變量挂脑,而Swift中的結(jié)構(gòu)體不僅可以定義屬性藕漱,還可以定義方法。因此崭闲,我們可以把Swfit結(jié)構(gòu)體看做是一種輕量級(jí)的類(lèi)肋联。

Swift中類(lèi)和結(jié)構(gòu)體的共同處在于:

  • 定義屬性用于存儲(chǔ)值
  • 定義方法用于提供功能
  • 定義下標(biāo)腳本用于訪問(wèn)值
  • 定義構(gòu)造器用于生成初始化值
  • 通過(guò)擴(kuò)展以增加默認(rèn)實(shí)現(xiàn)的功能
  • 實(shí)現(xiàn)協(xié)議以提供某種標(biāo)準(zhǔn)功能

Swift中類(lèi)和結(jié)構(gòu)體的不同處在于:

  • 結(jié)構(gòu)體不具有繼承性
  • 結(jié)構(gòu)體不具備運(yùn)行時(shí)強(qiáng)制類(lèi)型轉(zhuǎn)換
  • 結(jié)構(gòu)體不具備使用析構(gòu)器的能力
  • 結(jié)構(gòu)體不具備使用引用計(jì)數(shù)的能力

結(jié)構(gòu)體定義

// 結(jié)構(gòu)體定義使用struct關(guān)鍵字
struct MarkStruct {
    // 結(jié)構(gòu)體也有存儲(chǔ)屬性和計(jì)算屬性,這里只定義了存儲(chǔ)屬性
    var mark1: Int
    var mark2: Int
    var mark3: Int
}

// 所有結(jié)構(gòu)體都有一個(gè)自動(dòng)生成的成員逐一初始化構(gòu)造器,用于初始化結(jié)構(gòu)體實(shí)例中成員的屬性
// 順序必須和結(jié)構(gòu)體成員順序一致,必須包含所有的成員
var marks = MarkStruct(mark1: 98, mark2: 96, mark3: 100)

print(marks.mark1)  // return:98
print(marks.mark2)  // return:96
print(marks.mark3)  // return:100

結(jié)構(gòu)體定義屬性

// 結(jié)構(gòu)體定義屬性

struct Point {
    var x = 0.0
    var y = 0.0
}

struct MyPoint {
    // 定義存儲(chǔ)屬性
    var p = Point()
    // 定義計(jì)算屬性
    var point:Point {
        get {
            return p
        }
        set(newPoint) { // 修改newValue名為newPoint,本質(zhì)還是newValue
            p.x = newPoint.x
            p.y = newPoint.y
        }
    }
}

var p = Point(x: 10.0, y: 11.0)
var myPoint = MyPoint()
myPoint.point = p
print("x=\(myPoint.point.x),y=\(myPoint.point.y)") // return:x=10.0,y=11.0

結(jié)構(gòu)體的方法

// 結(jié)構(gòu)體的方法

// 結(jié)構(gòu)體內(nèi)部只有在構(gòu)造函數(shù)(init)中可以修改屬性的值,其他方法內(nèi)不能直接修改結(jié)構(gòu)體內(nèi)部屬性的值。
struct Rect {
    var width:Double
    var height:Double = 0.0
    
    // 給結(jié)構(gòu)體定義一個(gè)方法, 該方法屬于該結(jié)構(gòu)體
    // 結(jié)構(gòu)體中的成員方法必須使用某個(gè)實(shí)例調(diào)用
    // 成員方法可以訪問(wèn)成員屬性
    func getWidth() -> Double {
        return width
    }
}

var rect = Rect(width: 10.0, height: 20.0)
// 結(jié)構(gòu)體中的成員方法是和某個(gè)實(shí)例對(duì)象綁定在一起的, 所以誰(shuí)調(diào)用, 方法中訪問(wèn)的屬性就屬于誰(shuí)
print(rect.getWidth())  // return :10.0

var rect2 = Rect(width: 30.0, height: 20.0)
// 取得rect2這個(gè)對(duì)象的寬度
print(rect2.getWidth()) // retrun: 30.0

值類(lèi)型和引用類(lèi)型

值類(lèi)型被賦予給一個(gè)變量刁俭、常數(shù)或者本身被傳遞給一個(gè)函數(shù)的時(shí)候橄仍,實(shí)際上操作的是值的拷貝。
實(shí)際上牍戚,在Swift中侮繁,所有的基本類(lèi)型:整數(shù)、浮點(diǎn)數(shù)如孝、布爾值宪哩、字符串、數(shù)組和字典暑竟,都是值類(lèi)型,并且都是以結(jié)構(gòu)體的形式在后臺(tái)所實(shí)現(xiàn)育勺。
在Swift中但荤,所有的結(jié)構(gòu)體和枚舉都是值類(lèi)型。這意味著它們的實(shí)例涧至,以及實(shí)例中所包含的任何值類(lèi)型屬性腹躁,在代碼中傳遞的時(shí)候都會(huì)被復(fù)制。

值類(lèi)型賦值

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

// 創(chuàng)建一個(gè)結(jié)構(gòu)體
let hd = ReSolution(width: 1920, height: 1080)
// 結(jié)構(gòu)體賦值,實(shí)際上做的是拷貝操作,cinema和hd結(jié)構(gòu)體在內(nèi)存中各自占用獨(dú)立的空間
var cinema = hd
// 修改cinema結(jié)構(gòu)體,不會(huì)影響hd結(jié)構(gòu)體
cinema.width = 2048

print("cinema is now \(cinema.width) pixels wide") // return:2048
print("hd is still \(hd.width) pixels wide")       // return:1920

引用類(lèi)型賦值

與值類(lèi)型不同南蓬,引用類(lèi)型在被賦予到一個(gè)變量纺非、常量或者被傳遞到一個(gè)函數(shù)時(shí)哑了,操作的并不是其拷貝。因此烧颖,引用的是已存在的實(shí)例本身而不是其拷貝弱左。
類(lèi)就是引用類(lèi)型。

class ResolutionClass {
    var width = 0
    var height = 0
    init(width: Int,height: Int) {
        self.width = width
        self.height = height
    }
}

// 創(chuàng)建一個(gè)類(lèi)對(duì)象
let hdClass = ResolutionClass(width: 1920, height: 1080)
// 類(lèi)對(duì)象賦值,引用同一個(gè)內(nèi)存空間
var cinemaClass = hdClass
// 修改cinema對(duì)象,本質(zhì)上也是修改hdClass對(duì)象
cinemaClass.width = 2048
print("cinemaClass is now \(cinemaClass.width) pixels wide")  // return:2048
print("hdClass is also \(hdClass.width) pixels wide")         // return:2048

類(lèi)和結(jié)構(gòu)體的選擇

結(jié)構(gòu)體實(shí)例總是通過(guò)值傳遞炕淮,類(lèi)實(shí)例總是通過(guò)引用傳遞拆火。這意味兩者適用不同的任務(wù)。當(dāng)你的在考慮一個(gè)工程項(xiàng)目的數(shù)據(jù)構(gòu)造和功能的時(shí)候涂圆,你需要決定每個(gè)數(shù)據(jù)構(gòu)造是定義成類(lèi)還是結(jié)構(gòu)體们镜。

當(dāng)符合一條或多條以下條件時(shí),請(qǐng)考慮構(gòu)建結(jié)構(gòu)體:

  • 結(jié)構(gòu)體的主要目的是用來(lái)封裝少量相關(guān)簡(jiǎn)單數(shù)據(jù)值润歉。
  • 有理由預(yù)計(jì)一個(gè)結(jié)構(gòu)體實(shí)例在賦值或傳遞時(shí)模狭,封裝的數(shù)據(jù)將會(huì)被拷貝而不是被引用。
  • 任何在結(jié)構(gòu)體中儲(chǔ)存的值類(lèi)型屬性踩衩,也將會(huì)被拷貝嚼鹉,而不是被引用。
  • 結(jié)構(gòu)體不需要去繼承另一個(gè)已存在類(lèi)型的屬性或者行為九妈。
    合適的結(jié)構(gòu)體候選者包括:
  • 幾何形狀的大小
  • 一定范圍內(nèi)的路徑
  • 三維坐標(biāo)系內(nèi)一點(diǎn)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末反砌,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子萌朱,更是在濱河造成了極大的恐慌宴树,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晶疼,死亡現(xiàn)場(chǎng)離奇詭異酒贬,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)翠霍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)锭吨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人寒匙,你說(shuō)我怎么就攤上這事零如。” “怎么了锄弱?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵考蕾,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我会宪,道長(zhǎng)肖卧,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任掸鹅,我火速辦了婚禮塞帐,結(jié)果婚禮上拦赠,老公的妹妹穿的比我還像新娘。我一直安慰自己葵姥,他們只是感情好荷鼠,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著牌里,像睡著了一般颊咬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上牡辽,一...
    開(kāi)封第一講書(shū)人閱讀 49,806評(píng)論 1 290
  • 那天喳篇,我揣著相機(jī)與錄音,去河邊找鬼态辛。 笑死麸澜,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的奏黑。 我是一名探鬼主播炊邦,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼熟史!你這毒婦竟也來(lái)了馁害?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蹂匹,失蹤者是張志新(化名)和其女友劉穎碘菜,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體限寞,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡忍啸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了履植。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片计雌。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖玫霎,靈堂內(nèi)的尸體忽然破棺而出凿滤,到底是詐尸還是另有隱情,我是刑警寧澤庶近,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布翁脆,位于F島的核電站,受9級(jí)特大地震影響拦盹,放射性物質(zhì)發(fā)生泄漏鹃祖。R本人自食惡果不足惜溪椎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一普舆、第九天 我趴在偏房一處隱蔽的房頂上張望恬口。 院中可真熱鬧,春花似錦沼侣、人聲如沸祖能。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)养铸。三九已至,卻和暖如春轧膘,著一層夾襖步出監(jiān)牢的瞬間钞螟,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工谎碍, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鳞滨,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓蟆淀,卻偏偏與公主長(zhǎng)得像拯啦,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子熔任,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

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