標籤:oat 而不是 href 計算 vbscrip some pen 注意 字串類型
枚舉、結構體、類
註:本文為作者自己總結。過於基礎的就不再贅述 ,都是親自測試的結果。如有錯誤或者遺漏的地方。歡迎指正,一起學習。
1、枚舉
枚舉是用來定義一組通用類型的一組相關值 ,關鍵字enum ,case關鍵詞表明新的一行成員值將被定義。
enum Direction{ case East case West case South case North}
這裡定義了一個簡單的枚舉類型 , 裡面有四個枚舉元素 。
也能夠用一行的形式
enum Direction{ case East , West , South , North}
能夠這樣來訪問這個枚舉類型var dir = Direction.East 。這時候這個變數 dir 已經被判斷成Direction ,又一次賦值的時候 能夠直接用短文法dir = .West 。
- 相關值(Associated Values)
你能夠定義 Swift 的枚舉儲存不論什麼類型的相關值,假設須要的話,每一個成員的資料類型能夠是各不同樣的。
enum Barcode { case UPCA(Int , Int , Int ,Int ) case QRCode(String)}
你能夠這樣給它賦值var pro = Barcode.UPCA(8, 53627, 29009, 1) 。也能夠這樣改動pro = .QRCode("DSLEKWLJELJAIWFLWKJF")
這樣取值
switch pro{case .UPCA(let a1,let a2, let a3, let a4): print("\(a1) , \(a2) , \(a3) , \(a4)")case .QRCode(let s): print(s)}
你也能夠把let寫在最前面
switch pro{case let .UPCA( a1, a2, a3, a4): print("\(a1) , \(a2) , \(a3) , \(a4)")case let .QRCode(s): print(s)}
兩個得到同樣的結果 : DSLEKWLJELJAIWFLWKJF
- 給枚舉指定特定類型 (原始值)
你能夠給一個枚舉指定類型 。比方說String 類型 。
enum SignBuilding : String{ case Beijing = "天安門" case XiAn = "兵馬俑"}
這裡將 這個枚舉定義成 字串類型的 。
通過這樣能夠取到相應的值print(SignBuilding.Beijing.rawValue)
也能夠原始值隱式賦值
enum IntVal:Int { case Val1 = 1 , Val2 , Val3}
假設沒給Val1賦值 。預設是 0 。遞增是 1 ,也能夠 自己制定初始值 (這裡我們給定了初始值1)
也能夠使用原始值來初始化枚舉 let val = IntVal(rawValue: 2) print(val) //Optional(IntVal.Val2) ,這裡得到的結果是Optional類型 ,由於不是全部的數字都能匹配到相應的枚舉類型 。如 :let errorVal = IntVal(rawValue: 5) print(errorVal) //nil
官方還給出了遞迴枚舉 ,關鍵字 indirect 。可是我這邊嘗試了好多次 ,這個關鍵字也沒有變色 ,還會報錯 。
enum Calculate{ case Num(Int) indirect case Plus(Calculate,Calculate) indirect case ChenFa(Calculate,Calculate)}
在網上搜了下 , 由於是2.0的新特性 。網上也沒有太多的解釋。大家能夠研究下 。我也研究下 ,研究出來再來補上。
枚舉裡面還能夠有方法 ,只是不太推薦把 。全然能夠用結構體和方法 。
枚舉和結構體都是實值型別 。在傳遞的時候都是以拷貝的方式。
類是參考型別 ,傳遞的時候僅僅是傳遞一個引用 。
2、類和結構體
類 Class 結構體 struct 簡單的定義
struct myPoint{ var x = 0; var y = 0;}class Person { var name:String?; var age:Int?; var p1 = myPoint(x: 1,y: 2); var p = myPoint(); }
這裡定義了一個簡單的結構體和類,類中定義了幾個簡單的屬性 , 包含 一個結構體屬性 ,給出了兩種初始化的方法 。關於屬性的聲明能夠去看 Swift具體解釋之中的一個 ——– 變數聲明 。
Int , float 。 數組 字典 等 都是實值型別 後台都以結構體的方式實現
一般使用結構體的情況
- 結構體的主要目的是用來封裝少量 簡單的資料值
- 估計執行個體在賦值或傳遞過程中將會被拷貝 而不是引用
- 不論什麼在結構體中儲存的實值型別屬性也將被拷貝 而不是引用
- 不須要繼承已存在的類型 或者屬性 行為(結構體是沒有繼承的)
假設建立了一個結構體的執行個體。而且將這個執行個體賦值給一個常量 則無法改動其屬性 。就算是變數屬性也無法改動
let p1 = myPoint(x: 1,y: 1)
這裡我嘗試改動結構體中的變數x 報錯 。
參考型別賦給常量,仍然能夠改變其變數屬性。所以類的執行個體能夠賦值給一個常量
延遲儲存屬性是指當第一次被調用的時候才會計算其初始值的屬性。
在屬性聲明前使用lazy來標示一個延遲儲存屬性。 (懶載入)
注意:必須將延遲儲存屬性聲明成變數(使用var關鍵字),由於屬性的值在執行個體構造完畢之前可能無法得到。而常量屬性在構造過程完畢之前必須要有初始值,因此無法聲明成延遲屬性。
看下官方給的範例。
class DataImporter { /* DataImporter 是一個將外部檔案裡的資料匯入的類。 這個類的初始化會消耗不少時間。 */ var fileName = "data.txt" // 這是提供資料匯入功能}
class DataManager { lazy var importer = DataImporter() //這裡使用了懶載入 在第一次用到的時候才去建立這個執行個體 假設建立DataManager 就去建立DataImporter 有可能並不須要這個執行個體。浪費記憶體和時間 var data = [String]() // 這是提供資料管理功能}
let manager = DataManager()manager.data.append("Some data")manager.data.append("Some more data")// DataImporter 執行個體的 importer 屬性還沒有被建立
這裡能夠看到我們並沒有使用DataImporter , 所以在建立DataManager()的時候並不並不須要初始化DataImporter ,所以我們使用懶載入在這時候就節省了記憶體的開支。
可是。假設被標記位lazy的屬性 在沒有被初始化的時候被多個線程訪問 這時候 不能保證這個屬性僅僅被執行個體一次
我們能夠通過以下的方式定義一個僅僅讀屬性 。
var a = 1.2;var b:Double{ return a*4 }
- 類型屬性
無論這個類有多少個執行個體 ,它的類屬性 僅僅有一個 。
關鍵字 static
struct myStruct{ static var height = 19.3}
能夠直接通過結構體的名字或者類的名字來調用類型 屬性print(myStruct.height)
只是在類中有時候須要使用關鍵字class ,來同意它的子類重寫這個屬性 。
class myClass { static let name = "zhangsan " static var age = 21 static var status: Int { return 1 } //在定義計算型屬性的時候能夠使用 關鍵字 class 來支援子類對父類進行重寫 class var canOverrid: Int { return 10 }}
class sonClass: myClass { override static var canOverrid: Int { return 89 } //static let name = "zhangsan " //cannot override with a stored property ‘name‘}
這裡我們子類能夠重寫class 標記的類型屬性 。
- 方法
方法能夠分成執行個體方法和類型方法 。
類、結構體、枚舉都能夠定義執行個體方法;執行個體方法為給定類型的執行個體封裝了具體的任務與功能。類、結構體、枚舉也能夠定義類型方法;類型方法與類型本身相關聯。
結構體和枚舉能夠定義方法 是swift和oc的一大差別
類型方法就是在func 前面加static 類有時候可能須要加class 。
跟屬性的使用方法是一樣的,這裡就不在執行個體 。
實值型別的屬性不能在執行個體方法中被改動。可是有時候你確實想改動過。這時候 你能夠使用變異方法 。
關鍵字 mutating
struct Counter{ var count = 0 func getCount() ->Int{ return count } //由於實值型別的屬性不能在執行個體方法中被改動 這裡使用了變異方法 mutating func increment() { count++ }}var c = Counter()print(c.count) // 0print(c.getCount()) // 0c.increment()print(c.count) // 1
變異方法能夠給自己賦值
enum Level { case High , Mid ,Low mutating func next() { switch self { case .High: self = Mid case .Mid: self = Low default: self = High } }}var level = Level.Highlevel.next()print(level) //Level.Midlevel.next()print(level) //Level.Low
學習iOS。有他就夠了,小碼哥視頻,傳智、黑馬、各種swift書籍
Swift具體解釋之六----------------枚舉、結構體、類