Swift(十六)類、結構體匿值、枚舉和方法

d54a0fdbada6593eb7081404dc28df9ed91ad57a1ff1f-tC3wKL_fw658.jpeg

在swift當中, 除了類可以定義方法, 結構體和枚舉也可以定義方法, 這是Swift 與 C/Objective-C 的主要區(qū)別之一.

class Counter { 
//保持對當前計數(shù)器值的追蹤。
  var count = 0 
//increment讓計數(shù)器按一遞增
  func increment() { 
    count += 1 //注意. 此處不能使用count++, 在swift3.x里面, 已經(jīng)廢除++, --的寫法 
  } 
//incrementBy(amount: Int)讓計數(shù)器按一個指定的整數(shù)值遞增边酒;
  func incrementBy(amount: Int) { 
    count += amount 
  } 
//reset將計數(shù)器重置為0经柴。
  func reset() { 
    count = 0 
  } 
}

方法的使用, 與OC一樣, 使用, 點語法訪問

let counter = Counter() 
// 初始計數(shù)值是0 
counter.increment() 
// 計數(shù)值現(xiàn)在是1 
counter.incrementBy(amount: 5) //swift3.x寫法
//counter.incrementBy(5) , swift2.x寫法
// 計數(shù)值現(xiàn)在是6 
counter.reset() 
// 計數(shù)值現(xiàn)在是0 

self屬性

類型的每一個實例都有一個隱含屬性叫做self,self完全等同于該實例本身墩朦。你可以在一個實例的實例方法中使用這個隱含的self屬性來引用當前實例坯认。

上面例子中的increment方法還可以這樣寫:

func increment() { 
  self.count++ 
} 

實際上,你不必在你的代碼里面經(jīng)常寫self氓涣。不論何時牛哺,只要在一個方法中使用一個已知的屬性或者方法名稱,如果你沒有明確的寫self春哨,Swift 假定你是指當前實例的屬性或者方法荆隘。這種假定在上面的Counter中已經(jīng)示范了:Counter中的三個實例方法中都使用的是count(而不是self.count)。

使用這條規(guī)則的主要場景是實例方法的某個參數(shù)名稱與實例的某個屬性名稱相同的時候赴背。在這種情況下椰拒,參數(shù)名稱享有優(yōu)先權,并且在引用屬性時必須使用一種更嚴格的方式凰荚。這時你可以使用self屬性來區(qū)分參數(shù)名稱和屬性名稱燃观。

在實例方法中修改值類型

mutating方法(變異方法)

結構體和枚舉是值類型。一般情況下便瑟,值類型的屬性不能在它的實例方法中被修改缆毁。

如果你確實需要在某個具體的方法中修改結構體或者枚舉的屬性,你可以選擇變異(mutating)這個方法到涂,然后方法就可以從方法內(nèi)部改變它的屬性脊框;并且它做的任何改變在方法結束時還會保留在原始結構中。方法還可以給它隱含的self屬性賦值一個全新的實例践啄,這個新實例在方法結束后將替換原來的實例浇雹。

struct Point {
    var x = 0.0, y = 0.0
    //使用mutating關鍵字進行聲明, 來修改結構體和枚舉的屬性值
    mutating func moveByX(deltaX: Double, y deltaY: Double) {
        x += deltaX
        y += deltaY
    } 
}
var somePoint = Point(x: 1.0, y: 1.0)
somePoint.moveByX(deltaX: 2.0, y: 3.0)
print("The point is now at (\(somePoint.x), \(somePoint.y))")
//不能用聲明為常量(let)類型的結構體調用變異方法,因為常量的屬性不能被改變屿讽,即使想改變的是常量的變量屬性也不行
let fixedPoint = Point(x: 3.0, y: 3.0) //?正確寫法, 把fixedPoint結構體聲明為var
fixedPoint.moveByX(deltaX: 2.0, y: 3.0) //error ->  change 'let' to 'var' to make it mutable

在變異方法中給self賦值(Assigning to self Within a Mutating Method)

上面的例子可以改寫成

struct Point {
    var x = 0.0, y = 0.0
    mutating func moveByX(deltaX: Double, y deltaY: Double) {
        self = Point(x: x + deltaX, y: y + deltaY) //創(chuàng)建一個新的結構體, 并把它賦值給自己
    } 
}

var somePoint = Point(x: 1.0, y: 1.0)
somePoint.moveByX(deltaX: 2.0, y: 3.0)
print("The point is now at (\(somePoint.x), \(somePoint.y))")

枚舉的變異方法

//枚舉的變異方法可以把self設置為相同的枚舉類型中不同的成員:
enum TriStateSwitch {
    case Off, Low, High
    mutating func next() {
        switch self {
        case .Off: // case時別忘記使用(.)運算符, 否則 error: enum element 'Off' cannot be referenced as an instance member
            self = .Low
        case .Low:
            self = .High
        case .High:
            self = .Off
        }
    }
}
var ovenLight = TriStateSwitch.Low
ovenLight.next()
// ovenLight 現(xiàn)在等于 .High
ovenLight.next() 
// ovenLight 現(xiàn)在等于 .Off 

類型方法(Type Methods)

實例方法是被類型的某個實例調用的方法昭灵。你也可以定義類型本身調用的方法,這種方法就叫做類型方法伐谈。聲明類的類型方法烂完,在方法的func關鍵字之前加上關鍵字class;聲明結構體和枚舉的類型方法诵棵,在方法的func關鍵字之前加上關鍵字static抠蚣。

//類型方法和實例方法一樣用點語法調用。但是履澳,你是在類型層面上調用這個方法嘶窄,而不是在實例層面上調用
class SomeClass { 
  class func someTypeMethod() { 
    // type method implementation goes here 
    //在類型方法的方法體(body)中缓屠,self指向這個類型本身,而不是類型的某個實例护侮。對于結構體和枚舉來說敌完,這意味著你可以用self來消除靜態(tài)屬性和靜態(tài)方法參數(shù)之間的歧義(類似于我們在前面處理實例屬性和實例方法參數(shù)時做的那樣)。
  } 
} 
SomeClass.someTypeMethod()

//一般來說羊初,任何未限定的方法和屬性名稱滨溉,將會來自于本類中另外的類型級別的方法和屬性。一個類型方法可以調用本類中另一個類型方法的名稱长赞,而無需在方法名稱前面加上類型名稱的前綴晦攒。同樣,結構體和枚舉的類型方法也能夠直接通過靜態(tài)屬性的名稱訪問靜態(tài)屬性得哆,而不需要類型名稱前綴脯颜。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市贩据,隨后出現(xiàn)的幾起案子栋操,更是在濱河造成了極大的恐慌,老刑警劉巖饱亮,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件矾芙,死亡現(xiàn)場離奇詭異,居然都是意外死亡近上,警方通過查閱死者的電腦和手機剔宪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來壹无,“玉大人葱绒,你說我怎么就攤上這事《范В” “怎么了地淀?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長拒迅。 經(jīng)常有香客問我骚秦,道長她倘,這世上最難降的妖魔是什么璧微? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮硬梁,結果婚禮上前硫,老公的妹妹穿的比我還像新娘。我一直安慰自己荧止,他們只是感情好屹电,可當我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布阶剑。 她就那樣靜靜地躺著,像睡著了一般危号。 火紅的嫁衣襯著肌膚如雪牧愁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天外莲,我揣著相機與錄音猪半,去河邊找鬼。 笑死偷线,一個胖子當著我的面吹牛磨确,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播声邦,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼乏奥,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了亥曹?” 一聲冷哼從身側響起邓了,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎媳瞪,沒想到半個月后驶悟,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡材失,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年痕鳍,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片龙巨。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡笼呆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出旨别,到底是詐尸還是另有隱情诗赌,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布秸弛,位于F島的核電站铭若,受9級特大地震影響,放射性物質發(fā)生泄漏递览。R本人自食惡果不足惜叼屠,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望绞铃。 院中可真熱鬧镜雨,春花似錦、人聲如沸儿捧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至颓影,卻和暖如春各淀,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背诡挂。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工揪阿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人咆畏。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓南捂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親旧找。 傳聞我的和親對象是個殘疾皇子溺健,可洞房花燭夜當晚...
    茶點故事閱讀 44,927評論 2 355

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