swift學習-枚舉、結構體、類

Swift語言中,具有類特征的類型包括三種,即枚舉類型、結構類型(包括基本類型,基本類型實際都是結構類型的特例)、類。其中枚舉類型、結構類型是屬于值類型,類屬于引用類型。三種類型都可以添加屬性、方法、下標方法,能夠使用擴展進行功能擴展,使用協議等。

枚舉

枚舉定義了一種包含一組相關值的公共類型。枚舉是Swift中的一種與類類似的類型,具有許多傳統類才有的特征,例如計算屬性、實例方法,能夠通過擴展或協議增強功能等。

  • 枚舉定義,Swift 語言的枚舉類型的定義語法如下:
enum CompassPoint {
   case North
   case South
   case East
   case West
}

枚舉語法以一個關鍵字enum來標識,enum后面包含一個枚舉類型名字,枚舉定義全部放到一對大括號中。 在枚舉中定義的值稱為枚舉成員值,用case關鍵字來指示一個新的枚舉成員值。 與C和Objective-C語言的枚舉類型不同的是:在Swift中不需要為枚舉成員分配一個默認的整數值。 如果為枚舉成員提供值,該值可以是一個字符串、一個字符或者是一個任意整數或浮點數。枚舉成員值可以定義到一行中,并用逗號分割。

enum Planet {
   case Mercury,Venus,Earth,Mars,Jupiter,Saturn,Uranus,Neptune
}
  • 枚舉的使用
    可以為一個常量或變量分配一種枚舉類型的值,如:
var directionToHead =CompassPoint.West

以上定義的變量directionToHead可以推斷為是一種CompassPoint類型的枚舉變量,因此你可以設置該變量為CompassPoint類型的其它值,如:

directionToHead = .East //枚舉類型被省略

枚舉也能夠在switch語句中使用,用來匹配獨立的枚舉值:

directionToHead = .South
switch directionToHead {
case .North:
   println("Lots of planets have a north")
case .South:
   println("Watch out for penguins")
case .East:
   println("Where the sun rises")
case .West:
   println("Where the skies are blue")
}
  • 為枚舉成員分配相關值
    Swift中能夠為每一個枚舉成員規定一個任意類型的相關值,并且為每個枚舉成員規定的相關值的類型可以不同。
enum Barcode {
   case UPCA(Int,Int,Int)
   case QRCode(String)
}

該例子定義了一個類型為Barcode的枚舉類型,并定義了兩個枚舉值UPCA 和QRCode,并可以為枚舉值UPCA 分配一個多元組類型的相關值,為QRCode分配一個字符串類型的相關值,該例子沒有為枚舉值本身指定任何類型的值。
可以使用以上定義的枚舉為一個常量或變量賦值,如:

var productBarcode =Barcode.UPCA(8,85909_51226,3)

還可以在switch語句中使用該枚舉,并通過綁定常量或變量的方式引出其帶有的相關類型的值:

switch productBarcode {
case .UPCA(let numberSystem,let identifier,let check):
   println("UPC-A with value of\(numberSystem),\(identifier),\(check).")
case .QRCode(let productCode):
   println("QR code with value of\(productCode).")
}

如果枚舉成員的所有的相關值都作為常量被引出,或者所有的相關值都作為變量形式被引出,以上語法還可以簡寫為如下形式:

switch productBarcode {
case let .UPCA(numberSystem,identifier,check):
   println("UPC-A with value of\(numberSystem),\(identifier),\(check).")
case let .QRCode(productCode):
   println("QR code with value of\(productCode).")
}
  • 為枚舉分配原始值
    除了為枚舉成員分配相關的值外,還能為每個枚舉成員預分配一個同類型的原始值。這與C 語言為枚舉成員分配一個整數值類似,但Swift定義的原始值的類型可以是字符串、字符、或任意的整數或浮點數類型等,如:
enum ASCIIControlCharacter:Character {
         case Tab ="\t"
         case LineFeed ="\n"
         case CarriageReturn ="\r"
    }

該例子中,定義了一個含有三個枚舉成員的枚舉類型ASCIIControlCharacter,并指定其原始類型為字符類型,并為每個枚舉成員分配一個字符類型的默認原始值。
與C語言為枚舉成員指定值類似,Swift要求為枚舉的每個枚舉成員分配的原始值必須在枚舉聲明內唯一。當使用整數類型的原始值時,枚舉成員的其它原始值如果沒有指定,其能夠在第一個枚舉成員定義值的基礎上自動加1,如下所示:

enum Planet:Int {
   case Mercury =1,Venus,Earth,Mars,Jupiter,Saturn,Uranus,Neptune
}

為枚舉成員定義的原始值與為枚舉成員分配的相關值不同,枚舉成員的原始值是在枚舉第一次定義時被分配的,而枚舉成員的相關值雖然其類型也是在枚舉定義時指定,但其值是在使用枚舉類型創建一個常量或變量時設置的。
在Swift中,能夠使用枚舉成員的rawValue方法來獲取枚舉成員的原始值:

let earthsOrder = Planet.Earth.rawValue()

結構與類

  • 兩者比較
    在Swift中,結構和類功能上幾乎相同,兩者都具有如下相同的功能:
    • 可以定義屬性,用來存儲值;
    • 可以定義方法,用來提供功能;
    • 可以定義一個腳本方法,用來使用腳本語法來存取它們的值;
    • 能夠定義初始化方法來設置它們的初始狀態;
    • 能夠擴展來增加原先沒有實現的功能;
    • 能夠遵從相關協議來提供確定類型的標準功能。
      類在以下方面與結構存在差別:
    • 類能夠繼承,一個類能夠繼承它的超類的特性,而結構不能繼承;
    • 類允許在運行時檢查和解釋一個類實例的類型;
    • 類可以帶有析構函數,允許類的實例釋放它所分配的任何資源;
    • 引用計數允許一個類實例有多個引用。
    • 結構在代碼中總是以復制方式來傳遞,而不使用引用計數。
  • 類和結構的定義和實例化
    類和結構的定義采用相似的語法,類使用class關鍵字來指示,結構使用struct關鍵字來指示。
struct Resolution {
   var width =0
   var height =0
}
class VideoMode {
   var resolution =Resolution()
   var interlaced =false
   var frameRate =0.0
   var name:String?
}

每個新定義的類或結構都定義了一種新的類型。
上面例子定義了一種稱作Resolution的新的結構類型,其中包含和定義了兩個變量類型的屬性。還定義了一個稱作VideoMode的新類,該類定義和包含四個變量類型的屬性,其第一個屬性resolution還使用了剛剛定義的結構Resolution的實例進行了初始化。
類和結構中定義的變量或常量類型的屬性像通常變量和常量一樣進行初始化和賦值,屬性的類型可以根據為其提供的初始值進行推斷。
為類和結構創建實例的語法相同:

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

該例子采用了結構和類初始化最簡單的語法形式(結構和類的類型名面跟著一對圓括號)。該初始化語法為結構和類創建了一個新的各自的實例,并賦值給兩個常量,兩個實例的屬性也在該初始化方法中被初始化為它們的默認值。
在Swift中,所有的結構類型都會自動產生一個參數初始化方法,可以使用該方法來初始化和創建結構的新的實例及其成員屬性,新創建實例的屬性的初始值使用該初始化方法的參數傳進來的值,如:

let vga =Resolution(width:640,height:480)。

而類沒有提供相對應的默認的參數初始化方法。

在Swift中,與腳本語言類似,可以使用點語法的形式來存取一個結構或類實例的屬性以及子屬性,即讀取和設置其值:
讀取屬性的值:
println("The width of someResolution is\(someResolution.width)”)
  println("The width of someVideoMode is\(someVideoMode.resolution.width)”)
 設置一個屬性的值:
  someVideoMode.resolution.width = 1280
  • 結構、類與枚舉的類型
    在Swift中,結構和枚舉與其它基本類型(整型、浮點類型、布爾類型、字符串、數組和詞典,這些類型其實都是以結構類型實現的)一樣屬于值類型。這意味著它們在分配給一個變量或常量時或當它作為參數傳送給一個函數時,它們的實例以及它們包含的所有作為值類型的屬性一一被拷貝。
    在Swift中,為了提供性能,拷貝采用延遲拷貝的機制,即在實際用到時才拷貝。
 let     hd = Resolution(width:1920, height:1080)
      var cinema =hd

在該例子中,由于Resolution是一個結構類型,因此常量hd和變量cinema屬于Resolution結構類型的不同實例,因為在為變量cinema賦值時發生了拷貝行為。
與結構和枚舉不同,類的類型屬于引用類型。引用類型的實例在分配給一個變量或常量時或當它作為參數傳送給一個函數時,沒有拷貝發生。

let tenEighty =VideoMode()
      tenEighty.frameRate = 25.0
      let alsoTenEighty =tenEighty
      alsoTenEighty.frameRate =30.0

由于VideoMode屬于類,因此現在兩個常量tenEighty和alsoTenEighty引用的是相同的VideoMode實例,只是對應相同實例的不同的名字,因此這兩個常量的屬性值frameRate現在都等于30.0。
注意上面的tenEighty和alsoTenEighty被聲明為兩個常量,而不是變量,這是因為tenEighty和alsoTenEighty本身存儲的只是VideoMode的實例的引用值,而不是VideoMode實例本身,因此你通過它們對引用的類實例的屬性的改變,改變是類實例本身的屬性,而不是引用本身。
由于類是引用類型,就如以上例子所示,多個變量或常量可能引用一個類的相同的實例。為了判斷兩個常量或變量是否引用的是一個類的相同實例,Swift提供了兩個引用比較操作符: ‘===’與 ‘!==’。可以使用這兩個操作符來檢查兩個常量或變量是否引用的是相同的實例:

if tenEighty ===alsoTenEighty {
   println("tenEighty and alsoTenEighty refer to the same Resolution instance.")
}

在Swift中,一個常量或變量引用一個類的實例,這與C語言中的指針類似,但在Swift 中,引用不是直接指向內存中一個地址,因此不需要使用C語言中類似的指針符號’*’,用來代表一個引用或指針。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,119評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,382評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,038評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,853評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,616評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,112評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,192評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,355評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,869評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,727評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,928評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,467評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,165評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,570評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,813評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,585評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,892評論 2 372

推薦閱讀更多精彩內容