Protocols and Extensions 协议(接口)和扩展
Swift使用关键字protocol声明一个协议(接口):
类(classes),枚举(enumerations)和结构(structs)都可采用协议(protocol):
class SimpleClass: ExampleProtocol { var simpleDescription: String = "A very simple class." var anotherProperty: Int = 69105 func adjust() { simpleDescription += " Now 100% adjusted." } } var a = SimpleClass() a.adjust() let aDescription = a.simpleDescription struct SimpleStructure: ExampleProtocol { var simpleDescription: String = "A simple structure" mutating func adjust() { simpleDescription += " (adjusted)" } } var b = SimpleStructure() b.adjust() let bDescription = b.simpleDescription
练习:
照上例添加一个实现这个接口的枚举
请注意,上例中使用mutating关键词声明了一个方法adjust改动了SimpleStructure结构,而SimpleClass类则没有使用mutating关键字,因为类中的method可以随时改变类。(言外之意,结构中的方法要通过mutating关键字来标记更改结构,这个做法在后续具体翻译methods时会讲解到)
Swift使用extension关键字为已有的类型扩展功能,如增加新的方法或属性,你可以为别处声明的类型添加协议(接口),哪怕是引用过来的库或者框架:
extension Int: ExampleProtocol { var simpleDescription: String { return "The number \(self)" } mutating func adjust() { self += 42 } } 7.simpleDescription
练习:
使用extension关键字为Double类型添加一个求绝对值的属性
你可以像其它命名过的类型一样使用一个协议(接口),譬如,声明一个拥有不同类型但遵守同一个协议(接口)的对象集合。协议(接口)的值运行时,外部的方法是不可用的:
1 let protocolValue: ExampleProtocol = a
2 protocolValue.simpleDescription
3 // protocolValue.anotherProperty //这段代码的运行环境依赖上两个例子,我的理解是,假设常量protocolValue遵守ExampleProtocol协议,那么协议中的simpleDescription可以被引用,因为其在协议内部,而anotherProperty则不是协议内的方法,运行会报错,可以试着运行一下,看错误的结果。--by Joe.Huang
虽然ProtocolValue和SimpleClass类在同一个运行环境里面,但编译器会将其作用域放在ExampleProtocol里。也就是说,我们不能有意无意地使用协议(接口)外的方法或属性。
Generics 泛型
(提到泛型,肯定离不开泛型函数,~~~^_^~~~ 嘿嘿)
查看本栏目更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/extra/
通过尖括号<>定义泛型函数或类型(尖括内命名):
func repeat<ItemType>(item: ItemType, times: Int) -> ItemType[] { var result = ItemType[]() for i in 0..times { result += item } return result } repeat("knock", 4)
你可以在函数(func),方法(method)中使用泛型,同样地,类(classes),枚举(enumerations)和结构(structs)中也可以:
// 重载Swift标准库中的可选类型 enum OptionalValue<T> { case None case Some(T) } var possibleInteger: OptionalValue<Int> = .None possibleInteger = .Some(100)
有时需要对泛型做一些需求(requirements),比如需要某个泛型类型实现某个接口或继承自某个特定类型、两个泛型类型属于同一个类型等等,Swift 通过where
描述这些需求:
func anyCommonElements <T, U where T: Sequence, U: Sequence, T.GeneratorType.Element: Equatable, T.GeneratorType.Element == U.GeneratorType.Element> (lhs: T, rhs: U) -> Bool { for lhsItem in lhs { for rhsItem in rhs { if lhsItem == rhsItem { return true } } } return false } anyCommonElements([1, 2, 3], [3])
练习:
修改anyCommonElements函数,让其返回一个数组,内容是两个序列的共有元素
如果是简单的需要,你可以省略掉where关键字,比如<T where T: Equatable>可以简写为:<T: Equatable>。
翻译到此,《The Swift Programming Language》书中的语言简介部分已经译完了,后面的时间开始陆续翻译详解指南,工程量好大啊,希望有时间的同学能在github上一起帮忙翻译。^_^
作者:cnblogs Joe.Huang
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索接口
, 协议
, 关键字
, 方法
, 类型
, mutate
, 泛型swift
, 泛型结构
, 一个
, Swift语言简介
, 泛型for
泛型详解
swift 泛型协议、swift协议扩展、swift 泛型、swift3.0 泛型、swift3 泛型,以便于您获取更多的相关知识。