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类型添加一个求绝对值的属性

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

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

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

Generics 泛型

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

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

 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上一起帮忙翻译。^_^

谢谢,Swifter-QQ群:362232993,同好者进~

github地址:https://github.com/Joejo/Swift-lesson-for-chinese

Swift中文教程(七)--协议,扩展和泛型的更多相关文章

  1. Swift中文教程(四)--函数与闭包

    原文:Swift中文教程(四)--函数与闭包 Function 函数 Swift使用func关键字来声明变量,函数通过函数名加小括号内的参数列表来调用.使用->来区分参数名和返回值的类型: fu ...

  2. Swift中文教程(一)--欢迎来到Swift的世界

    原文:Swift中文教程(一)--欢迎来到Swift的世界 Apple凌晨时在WWDC发布了Swift编程语言,语法简介我很喜欢,市面上没有完整的中文教程,我在ibooks里面下载了英文原版,现在开始 ...

  3. Swift中文教程(二)--简单值

    原文:Swift中文教程(二)--简单值 Swift使用let关键字声明常量,var关键字声明变量.常量无需在编译时指定,但至少要被赋值一次.也就是说,赋值一次多次使用: var myVariable ...

  4. Swift中文教程(三)--流程控制

    原文:Swift中文教程(三)--流程控制 Swift用if和switch编写条件控制语句,用for-in,for,while和do-while编写循环.条件控制语句和循环语句中,小括号是可选的,但花 ...

  5. Swift中文教程(六)--枚举和结构

    原文:Swift中文教程(六)--枚举和结构 Enumerations 枚举 使用 enum 来创建一个枚举.跟Classes(类)和其他类型的命名方式一样,枚举也可以有Method(方法). enu ...

  6. Swift中文教程(五)--对象和类

    原文:Swift中文教程(五)--对象和类 Class 类 在Swift中可以用class关键字后跟类名创建一个类.在类里,一个属性的声明写法同一个常量或变量的声明写法一样,除非这个属性是在类的上下文 ...

  7. Apple Swift 中文教程 高速參考 基本的语法

    总的来说.语法有java的味道,也有python的味道,还有swift自己的味道. 有些语法还是挺不伦不类的,不太好理解,即使你有几年的java或python经验,也不见得有些语法你能非常轻松的看明确 ...

  8. Swift中文教程(二)基本运算符

    1.基本运算符 运算符是一种特定的符号或表达式,用来检验.改动或合并变量.比如,用求和运算符+能够对两个数字进行求和(如let i = 1 + 2):略微复杂一点的样例有逻辑与操作符&& ...

  9. Swift中文教程 第2章 基本运算符 (20140604更新)

    今天我在下午又进行了新的翻译,之前我翻译的大家有没有看啊,感觉如何,我昨天下午不小心点了什么原先的文章都没了,大家的评论也没了,现在我也找不回来了,希望大家能继续给我新的评论和支持点个推荐,毕竟现在学 ...

随机推荐

  1. AtCoder 2376 Black and White Tree

    D - Black and White Tree Time limit : 2sec / Memory limit : 256MB Score : 900 points Problem Stateme ...

  2. SQL表操作习题6 36~45题

  3. requestFeature() must be called before adding content

    错误:requestFeature() must be called before adding content 原因: Android去掉标题栏点菜单键程序崩溃 在安卓以前的版本中,我们会使用以下两 ...

  4. android开发之自定义圆形ImagView

    在日常使用中我们经常会使用到圆形的图片,但是android系统中并没有默认的圆形控件,所以我们需要自己来写一个自定义的ImagView来显示一张圆形的图片,下面先看效果 详细的方法是我们自定义一个类, ...

  5. java 中的VO,PO,DTO,DO对象

    经常会接触到VO,DO,DTO的概念,本文从领域建模中的实体划分和项目中的实际应用情况两个角度,对这几个概念进行简析. 得出的主要结论是:在项目应用中,VO对应于页面上需要显示的数据(表单),DO对应 ...

  6. 使用Hibernate框架来更新对象的注意事项

    Hibernate在更新对象的时候,如果对象的有些属性没有设置,那么在更新的时候,会被默认为空. 特别在更新表单对象的时候. 例子: 如: Department部门类 该部门类有以下属性:  id : ...

  7. ElasticSearch 结构化搜索

    1.介绍 结构化搜索(Structured search) 是指有关探询那些具有内在结构数据的过程.比如日期.时间和数字都是结构化的:它们有精确的格式,我们可以对这些格式进行逻辑操作. 比较常见的操作 ...

  8. [转载]How to Install Firefox 33 on CentOS, Redhat and Other Linux Distributions

    FROM: http://tecadmin.net/install-firefox-on-linux/ Firefox 33 has been released for Systems and And ...

  9. 13 Basic Cat Command Examples in Linux

    FROM: http://www.tecmint.com/13-basic-cat-command-examples-in-linux/ The cat (short for “concatenate ...

  10. mysql 存储过程 演示样例代码

    drop procedure if exists P_SEQUENCE; /** 暂省略包 @AUTO LIANGRUI 2014/6/27 T_PRO_PRODUCT 表 排序 对整个表进行按序号排 ...