1. 程式人生 > >Swift具體解釋之六----------------枚舉、結構體、類

Swift具體解釋之六----------------枚舉、結構體、類

vbs 元素 zha cannot status popu 錯誤 san more

枚舉、結構體、類

註:本文為作者自己總結。過於基礎的就不再贅述 ,都是親自測試的結果。如有錯誤或者遺漏的地方。歡迎指正,一起學習。


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 。 數組 字典 等 都是值類型 後臺都以結構體的方式實現
一般使用結構體的情況

  1. 結構體的主要目的是用來封裝少量 簡單的數據值
  2. 估計實例在賦值或傳遞過程中將會被拷貝 而不是引用
  3. 不論什麽在結構體中存儲的值類型屬性也將被拷貝 而不是引用
  4. 不須要繼承已存在的類型 或者屬性 行為(結構體是沒有繼承的)

假設創建了一個結構體的實例。而且將這個實例賦值給一個常量 則無法改動其屬性 。就算是變量屬性也無法改動

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) // 0
print(c.getCount()) // 0
c.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.High
level.next()
print(level)  //Level.Mid
level.next()
print(level)   //Level.Low

學習iOS。有他就夠了,小碼哥視頻,傳智、黑馬、各種swift書籍

Swift具體解釋之六----------------枚舉、結構體、類