Swift小結
不同的字元可能會佔用不同數量的記憶體空間,所以要知道Character的確定位置,就必須從String開頭遍歷每一個 Unicode 標量直到結尾。因此,Swift 的字串不能用整數(integer)做索引。
如果兩個字串(或者兩個字元)的可擴充套件的字形群集是標準相等的,那就認為它們是相等的。在這個情況 下,即使可擴充套件的字形群集是有不同的 Unicode 標量構成的,只要它們有同樣的語言意義和外觀,就認為它們標 準相等。
var oddDigits: Set = [1, 3, 5, 7, 9] let evenDigits: Set = [0, 2, 4, 6, 8] let singleDigitPrimeNumbers: Set = [2, 3, 5, 7] oddDigits.union(evenDigits).sorted() // 取並集 oddDigits.subtract(singleDigitPrimeNumbers) // 剔除交集 evenDigits.symmetricDifference(singleDigitPrimeNumbers).sorted() // 交集取反

圖片.png
必須將延遲儲存屬性宣告成變數(使用var關鍵字),因為屬性的初始值可能在例項構造完成之後才會得到。而常量屬性在構造過程完成之前必須要有初始值,因此無法宣告成延遲屬性。
當值型別(列舉、結構體)的例項被宣告為常量的時候,它的所有屬性也就成了常量。屬於引用型別的類(class)則不一樣。把一個引用型別的例項賦給一個常量後,仍然可以修改該例項的變數屬性。
必須使用var關鍵字定義計算屬性,包括只讀計算屬性,因為它們的值不是固定的。let關鍵字只用來宣告常量屬性,表示初始化後再也無法修改的值。
跟例項的儲存型屬性不同,必須給儲存型型別屬性指定預設值,因為型別本身沒有構造器,也就無法在初始化過程中使用構造器給型別屬性賦值。儲存型型別屬性是延遲初始化的,它們只有在第一次被訪問的時候才會被初始化。即使它們被多個執行緒同時訪問,系統也保證只會對其進行一次初始化,並且不需要對其使用lazy修飾符。
func stepForward(_ input: Int) -> Int { return input + 1 } func stepBackward(_ input: Int) -> Int { return input - 1 } func cal(isAdd: Bool) -> (Int) -> Int { if isAdd { return stepForward } return stepBackward } // 等價於 func caculate(isAdd: Bool) -> (Int) -> Int { if isAdd { func stepFor(input: Int) -> Int { return input + 1 } return stepFor } else { func stepBack(input: Int) -> Int { return input - 1 } return stepBack } } // 呼叫1 cal(isAdd: true)(1) // 呼叫2 caculate(isAdd: true)(1)
型別屬性語法
在 C 或 Objective-C 中,與某個型別關聯的靜態常量和靜態變數,是作為全域性(global)靜態變數定義的。但 是在 Swift 中,型別屬性是作為型別定義的一部分寫在型別最外層的花括號內,因此它的作用範圍也就在型別支 持的範圍內。
使用關鍵字 static 來定義型別屬性。在為類定義計算型型別屬性時,可以改用關鍵字 class 來支援子類對父 類的實現進行重寫。
例如:
struct SomeStructure { static var storedTypeProperty = "Some value." static var computedTypeProperty: Int { return 1 } } enum SomeEnumeration { static var storedTypeProperty = "Some value." static var computedTypeProperty: Int { return 6 } } class SomeClass { static var storedTypeProperty = "Some value." static var computedTypeProperty: Int { return 27 } class var overrideableComputedTypeProperty: Int { return 107 } }
獲取和設定型別屬性的值
跟例項屬性一樣,型別屬性也是通過點運算子來訪問。但是,型別屬性是通過型別本身來訪問,而不是通過實
例。
例如:
print(SomeStructure.storedTypeProperty) // 列印 "Some value." SomeStructure.storedTypeProperty = "Another value." print(SomeStructure.storedTypeProperty) // 列印 "Another value.” print(SomeEnumeration.computedTypeProperty) // 列印 "6" print(SomeClass.computedTypeProperty) // 列印 "27"
在例項方法中修改值型別
結構體和列舉是值型別。預設情況下,值型別的屬性不能在它的例項方法中被修改。
但是,如果你確實需要在某個特定的方法中修改結構體或者列舉的屬性,你可以為這個方法選擇 可變(mutatin g) 行為,然後就可以從其方法內部改變它的屬性;並且這個方法做的任何改變都會在方法執行結束時寫回到原始 結構中。方法還可以給它隱含的 self 屬性賦予一個全新的例項,這個新例項在方法結束時會替換現存例項。
例如:如果沒有 mutating
,將報錯 Left side of mutating operator isn't mutable: 'self' is immutable
struct Point { var x = 0.0, y = 0.0 mutating func moveByX(deltaX: Double, y deltaY: Double) { x += deltaX y += deltaY } }
列舉的可變方法可以把 self
設定為同一列舉型別中不同的成員:
例如:
enum TriStateSwitch { case Off, Low, High mutating func next() { switch self { case .Off: self = .Low case .Low: self = .High case .High: self = .Off } } } var ovenLight = TriStateSwitch.Low ovenLight.next() // ovenLight 現在等於 .High ovenLight.next() // ovenLight 現在等於 .Off
型別方法
例項方法是被某個型別的例項呼叫的方法。你也可以定義在型別本身上呼叫的方法,這種方法就叫做型別方 法。在方法的 func 關鍵字之前加上關鍵字 static ,來指定型別方法。類還可以用關鍵字 class 來允許子類重寫 父類的方法實現。
注意
在 Objective-C 中,你只能為 Objective-C 的類型別(classes)定義型別方法(type-level methods)。在 Swift 中,你可以為所有的類、結構體和列舉定義型別方法。每一個型別方法都被它所支援的型別顯式包含。