PRotocols and Extensions 協議(接口)和擴展
Swift使用關鍵字protocol聲明一個協議(接口):
類(classes),枚舉(enumerations)和結構(structs)都可采用協議(protocol):
1 class SimpleClass: ExampleProtocol { 2 var simpleDescription: String = "A very simple class." 3 var anotherProperty: Int = 69105 4 func adjust() { 5 simpleDescription += " Now 100% adjusted." 6 } 7 } 8 var a = SimpleClass() 9 a.adjust()10 let aDescription = a.simpleDescription11 12 struct SimpleStructure: ExampleProtocol {13 var simpleDescription: String = "A simple structure"14 mutating func adjust() {15 simpleDescription += " (adjusted)"16 }17 }18 var b = SimpleStructure()19 b.adjust()20 let bDescription = b.simpleDescription
練習:
照上例添加一個實現這個接口的枚舉
請注意,上例中使用mutating關鍵詞聲明了一個方法adjust改動了SimpleStructure結構,而SimpleClass類則沒有使用mutating關鍵字,因為類中的method可以隨時改變類。(言外之意,結構中的方法要通過mutating關鍵字來標記更改結構,這個做法在后續具體翻譯methods時會講解到)
Swift使用extension關鍵字為已有的類型擴展功能,如增加新的方法或屬性,你可以為別處聲明的類型添加協議(接口),哪怕是引用過來的庫或者框架:
1 extension Int: ExampleProtocol {2 var simpleDescription: String {3 return "The number /(self)"4 }5 mutating func adjust() {6 self += 427 }8 }9 7.simpleDescription
練習:
使用extension關鍵字為Double類型添加一個求絕對值的屬性
你可以像其它命名過的類型一樣使用一個協議(接口),譬如,聲明一個擁有不同類型但遵守同一個協議(接口)的對象集合。協議(接口)的值運行時,外部的方法是不可用的:
1 let protocolValue: ExampleProtocol = a2 protocolValue.simpleDescription3 // protocolValue.anotherProperty //這段代碼的運行環境依賴上兩個例子,我的理解是,假設常量protocolValue遵守ExampleProtocol協議,那么協議中的simpleDescription可以被引用,因為其在協議內部,而anotherProperty則不是協議內的方法,運行會報錯,可以試著運行一下,看錯誤的結果。--by Joe.Huang
雖然ProtocolValue和SimpleClass類在同一個運行環境里面,但編譯器會將其作用域放在ExampleProtocol里。也就是說,我們不能有意無意地使用協議(接口)外的方法或屬性。
Generics 泛型
(提到泛型,肯定離不開泛型函數,~~~^_^~~~ 嘿嘿)
通過尖括號<>定義泛型函數或類型(尖括內命名):
1 func repeat<ItemType>(item: ItemType, times: Int) -> ItemType[] {2 var result = ItemType[]()3 for i in 0..times {4 result += item5 }6 return result7 }8 repeat("knock", 4)
你可以在函數(func),方法(method)中使用泛型,同樣地,類(classes),枚舉(enumerations)和結構(structs)中也可以:
1 // 重載Swift標準庫中的可選類型2 enum OptionalValue<T> {3 case None4 case Some(T)5 }6 var possibleInteger: OptionalValue<Int> = .None7 possibleInteger = .Some(100)
有時需要對泛型做一些需求(requirements),比如需要某個泛型類型實現某個接口或繼承自某個特定類型、兩個泛型類型屬于同一個類型等等,Swift 通過where
描述這些需求:
1 func anyCommonElements <T, U where T: Sequence, U: Sequence, T.GeneratorType.Element: Equatable, T.GeneratorType.Element == U.GeneratorType.Element> (lhs: T, rhs: U) -> Bool { 2 for lhsItem in lhs { 3 for rhsItem in rhs { 4 if lhsItem == rhsItem { 5 return true 6 } 7 } 8 } 9 return false10 }11 anyCommonElements([1, 2, 3], [3])
練習:
修改anyCommonElements函數,讓其返回一個數組,內容是兩個序列的共有元素
如果是簡單的需要,你可以省略掉where關鍵字,比如<T where T: Equatable>可以簡寫為:<T: Equatable>。
翻譯到此,《The Swift Programming Language》書中的語言簡介部分已經譯完了,后面的時間開始陸續翻譯詳解指南,工程量好大啊,希望有時間的同學能在github上一起幫忙翻譯。^_^
謝謝,Swifter-QQ群:362232993,同好者進~
github地址:https://github.com/Joejo/Swift-lesson-for-chinese
新聞熱點
疑難解答