Swift中文教程(七)--协议,扩展和泛型

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

PRotocols and Extensions 协议(接口)和扩展

Swift使用关键字protocol声明一个协议(接口):

类(classes),枚举(enumerations)和结构(structs)都可采用协议(protocol):

1classSimpleClass: ExampleProtocol {2var simpleDescription: String ="A very simple class."3var anotherProperty: Int = 691054func adjust() {5simpleDescription +="Now 100% adjusted."6}7}8var a =SimpleClass()9a.adjust()10let aDescription =a.simpleDescription1112struct SimpleStructure: ExampleProtocol {13var simpleDescription: String ="A simple structure"14mutating func adjust() {15simpleDescription +="(adjusted)"16}17}18var b =SimpleStructure()19b.adjust()20let bDescription = b.simpleDescription

练习:

照上例添加一个实现这个接口的枚举

请注意,上例中使用mutating关键词声明了一个方法adjust改动了SimpleStructure结构,而SimpleClass类则没有使用mutating关键字,因为类中的method可以随时改变类。(言外之意,结构中的方法要通过mutating关键字来标记更改结构,这个做法在后续具体翻译methods时会讲解到)

Swift使用extension关键字为已有的类型扩展功能,如增加新的方法或属性,你可以为别处声明的类型添加协议(接口),哪怕是引用过来的库或者框架:

1extension Int: ExampleProtocol {2var simpleDescription: String {3return"The number \(self)"4}5mutatingfunc adjust() {6self += 427}8}97.simpleDescription

练习:

使用extension关键字为Double类型添加一个求绝对值的属性

你可以像其它命名过的类型一样使用一个协议(接口),譬如,声明一个拥有不同类型但遵守同一个协议(接口)的对象集合。协议(接口)的值运行时,外部的方法是不可用的:

1let protocolValue: ExampleProtocol =a2protocolValue.simpleDescription3// protocolValue.anotherProperty //这段代码的运行环境依赖上两个例子,我的理解是,假设常量protocolValue遵守ExampleProtocol协议,那么协议中的simpleDescription可以被引用,因为其在协议内部,而anotherProperty则不是协议内的方法,运行会报错,可以试着运行一下,看错误的结果。--by Joe.Huang

虽然ProtocolValue和SimpleClass类在同一个运行环境里面,但编译器会将其作用域放在ExampleProtocol里。也就是说,我们不能有意无意地使用协议(接口)外的方法或属性。

Generics 泛型

(提到泛型,肯定离不开泛型函数,~~~^_^~~~ 嘿嘿)

通过尖括号<>定义泛型函数或类型(尖括内命名):

1func repeat<ItemType>(item: ItemType, times: Int) ->ItemType[] {2var result =ItemType[]()3foriin0..times {4result +=item5}6returnresult7}8repeat("knock", 4)

你可以在函数(func),方法(method)中使用泛型,同样地,类(classes),枚举(enumerations)和结构(structs)中也可以:

1// 重载Swift标准库中的可选类型2enum OptionalValue<T>{3case None4case Some(T)5}6var possibleInteger: OptionalValue<Int> =.None7possibleInteger = .Some(100)

有时需要对泛型做一些需求(requirements),比如需要某个泛型类型实现某个接口或继承自某个特定类型、两个泛型类型属于同一个类型等等,Swift 通过where描述这些需求:

1func anyCommonElements <T, UwhereT: Sequence, U: Sequence, T.GeneratorType.Element: Equatable, T.GeneratorType.Element == U.GeneratorType.Element> (lhs: T, rhs: U) ->Bool {2forlhsIteminlhs {3forrhsIteminrhs {4iflhsItem ==rhsItem {5returntrue6}7}8}9returnfalse10}11anyCommonElements([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

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航