update 02/21 and 03/10

This commit is contained in:
numbbbbb
2014-06-10 12:14:55 +08:00
parent 7d716b5daf
commit 9eddc9af5a
41 changed files with 637 additions and 184 deletions

View File

@ -46,7 +46,7 @@
<div class="book" data-level="1.1" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="1.1" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_9">
<section class="normal" id="section-gitbook_6">
<h1 id="-swift">关于 Swift</h1>
<p>Swift 是一种新的编程语言,用于编写 iOS 和 OS X 应用。Swift 结合了 C 和 Objective-C 的优点并且不受C的兼容性的限制。Swift 使用安全的编程模式并添加了很多新特性这将使编程更简单扩展性更强也更有趣。除此之外Swift 还支持人见人爱的 Cocoa 和 Cocoa Touch 框架。拥有了这些特性Swift将重新定义软件开发。</p>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="1.2" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="1.2" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_10">
<section class="normal" id="section-gitbook_7">
<h1 id="swift-">Swift 初见</h1>
<p>本页内容包括:</p>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="1" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="1" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_11">
<section class="normal" id="section-gitbook_8">
<h1 id="-swift">欢迎使用 Swift</h1>
<p>在本章中您将了解 Swift 的特性和开发历史,并对 Swift 有一个初步的了解。</p>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="2.1" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="2.1" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_13">
<section class="normal" id="section-gitbook_10">
<h1 id="-">基础部分</h1>
<p>Swift 是 iOS 和 OS X 应用开发的一门新语言。然而,如果你有 C 或者 Objective-C 开发经验的话,你会发现 Swift 的很多内容都是你熟悉的。</p>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="2.2" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="2.2" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_35">
<section class="normal" id="section-gitbook_32">
<h1 id="-">基础运算符</h1>
<p>运算符是检查, 改变, 合并值的特殊符号或短语. 例如, 加号 <code>+</code> 把计算两个数的和(如 <code>let i = 1 + 2</code>). 复杂些的运行算包括逻辑与<code>&amp;&amp;</code>(如 <code>if enteredDoorCode &amp;&amp; passedRetinaScan</code>), 还有自增运算符 <code>++i</code> 这样让自身加一的便捷运算.</p>
@ -713,7 +713,7 @@ let c = a++ // a 现在 2, 但 c 是 a 自增前的值 1
<p>数值的正负号可以使用前缀 <code>-</code> (即单目负号) 来切换:</p>
<pre><code class="lang-swift">let three = 3
let minusThree = -three // minusThree 等于 -3
let plusThree = -minusThree // plusThree 等于 3, o&quot;负负3&quot;
let plusThree = -minusThree // plusThree 等于 3, 或 &quot;负负3&quot;
</code></pre>
<p>单目负号写在操作数之前, 中间没有空格.</p>
<h1 id="-">单目正号</h1>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="2.3" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="2.3" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_14">
<section class="normal" id="section-gitbook_11">
<h1 id="-strings-and-characters-">字符串和字符 (Strings and Characters)</h1>
<p>本页包含内容:</p>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="2.4" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="2.4" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_26">
<section class="normal" id="section-gitbook_23">
<h1 id="-collection-types-">集合类型 (Collection Types)</h1>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="2.5" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="2.5" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_27">
<section class="normal" id="section-gitbook_24">
<h1 id="-">控制流</h1>
<p>Swift提供了类似C语言的流程控制结构包括将任务执行多次的<code>for</code><code>while</code>循环,基于特定条件选择执行不同分支的<code>if</code><code>switch</code>语句,还有控制流程跳转到其他代码的<code>break</code><code>continue</code>语句。</p>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="2.6" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="2.6" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_28">
<section class="normal" id="section-gitbook_25">
<h1 id="-functions-">函数Functions</h1>
<p>本页包含内容:</p>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="2.7" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="2.7" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_29">
<section class="normal" id="section-gitbook_26">
<h1 id="-">闭包</h1>
<p>本页内容包含:</p>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="2.8" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="2.8" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_30">
<section class="normal" id="section-gitbook_27">
<h1 id="-">枚举</h1>
<p>本页内容包含:</p>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="2.9" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="2.9" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_31">
<section class="normal" id="section-gitbook_28">
<h3 id="-">类和结构体</h3>
<p>本页包含内容:</p>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="2.10" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="2.10" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_32">
<section class="normal" id="section-gitbook_29">
<h1 id="-properties-">属性 (Properties)</h1>
<p><strong>属性</strong>将值跟特定的类、结构或枚举关联。一种是存储属性,把常量或变量的值作为实例的一部分,一种是计算属性,它计算一个值。计算属性可以用于类、结构和枚举里,存储属性只能用于类和结构。</p>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="2.11" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="2.11" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_33">
<section class="normal" id="section-gitbook_30">
<h1 id="-methods-">方法(Methods)</h1>
<p><strong>方法</strong>是与某些特定类型相关联的功能/函数。类、结构体、枚举都可以定义实例方法;实例方法为指定类型的实例封装了特定的任务与功能。类、结构体、枚举也可以定义类(型)方法(type itself)类型方法与类型自身相关联。类型方法与Objective-C中的类方法(class methods)相似。</p>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="2.12" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="2.12" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_34">
<section class="normal" id="section-gitbook_31">
<h1 id="-subscripts-">下标 (Subscripts)</h1>
<p>下标可以定义在类(Class)、结构体(structures)和枚举(enumerations)这些目标中,可以认为是访问对象、集合或序列的快捷方式。举例来说,用下标访问一个数组(Array)实例中的元素可以这样写 <code>someArray[index]</code> ,访问字典(Dictionary)实例中的元素可以这样写 <code>someDictionary[key]</code>,而不需要再调用实例的某个方法来获得元素的值。</p>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="2.13" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="2.13" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_12">
<section class="normal" id="section-gitbook_9">
<h1 id="-">继承</h1>
<p>一个类可以继承另一个类的方法属性和其它特性。当一个类继承其它类继承类叫子类被继承类叫超类或父类。在Swift中继承是区分「类」与其它类型的一个基本特征。</p>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="2.14" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="2.14" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="2.15" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="2.15" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_37">
<section class="normal" id="section-gitbook_34">
<h1 id="-">析构过程</h1>
<p>在一个类的实例被释放之前析构函数被立即调用。用关键字deinit来标示析构函数类似于初始化函数用init来标示。析构函数只适用于类类型。</p>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="2.16" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="2.16" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_38">
<section class="normal" id="section-gitbook_35">
<h1 id="-">自动引用计数</h1>
<p>本页包含内容:</p>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="2.17" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="2.17" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_39">
<section class="normal" id="section-gitbook_36">
<h1 id="optional-chaining">Optional Chaining</h1>
<p>可选链Optional Chaining是一种可以请求和调用属性、方法及子脚本的过程它的自判断性体现于请求或调用的目标当前可能为空<code>nil</code>)。如果自判断的目标有值,那么调用就会成功;相反,如果选择的目标为空(<code>nil</code>),则这种调用将返回空(<code>nil</code>)。多次请求或调用可以被链接在一起形成一个链,如果任何一个节点为空(<code>nil</code>)将导致整个链失效。</p>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="2.18" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="2.18" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_40">
<section class="normal" id="section-gitbook_37">
<h1 id="-type-casting-">类型检查Type Casting</h1>
<p>ps为了方便各位检验所以保留了英文可删。

View File

@ -46,7 +46,7 @@
<div class="book" data-level="2.19" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="2.19" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_41">
<section class="normal" id="section-gitbook_38">
<h1 id="-">类型嵌套</h1>
<p>本页包含内容:</p>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="2.20" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="2.20" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_42">
<section class="normal" id="section-gitbook_39">
<h1 id="-extensions-">扩展Extensions</h1>
<hr>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="2.21" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="2.21" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,49 +587,47 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_44">
<section class="normal" id="section-gitbook_41">
<h1 id="-">协议</h1>
<p><code>Protocol(协议)</code>定义了用于完成某项任务或功能的方法,属性等,它不具备任何功能的细节实现,只用来<strong>统一</strong>方法,属性的名称和其类型.(<em>译者注: 其他语言中也<code>Portocol</code> 称为 <code>Interface(接口)</code></em> ).协议可以被<code>类,枚举,结构体</code>采纳并实现,任意满足协议要求的<code>,枚举,结构体</code>被称<code>协议遵循者</code>.</p>
<p>协议可以要求其<code>遵循者</code>必须具备的某些特定的<code>属性,方法,操作符,下标</code>.</p>
<p><code>Protocol(协议)</code>用于<strong>统一</strong>方法属性的名称,而不实现任何功能,(<em>译者注: 协议在其他语言中也称作<code>接口(Interface)</code></em>).<code>协议</code>能够被<code></code>,<code>枚举</code>,<code>结构体</code>实现,满足协议要求的<code></code>,<code>枚举</code>,<code>结构体</code>被称为协议的<code>遵循者</code>.</p>
<p><code>遵循者</code>需要提供<code>协议</code>指定的成员,如<code>属性</code>,<code>方法</code>,<code>操作符</code>,<code>下标</code>.</p>
<h2 id="-">协议的语法</h2>
<p><code>协议</code>的定义<code>类,结构体,枚举</code>的定义非常相似:</p>
<p><code>协议</code>的定义<code>类,结构体,枚举</code>的定义非常相似,如下所示:</p>
<pre><code>protocol SomeProtocol {
// 此处书写协议内容
// 协议内容
}
</code></pre><p><code>型名称</code>后加上<code>协议名称</code> ,并用冒号<code>:</code>分隔,从而实现协议;实现多个协议时,各协议之间用逗号<code>,</code>分隔.</p>
<pre><code>struct SomeStructure: FirstProtocol, AnotherProtocol{
// 此处书写结构体的定义
</code></pre><p><code></code>,<code>结构体</code>,<code>枚举</code>的名称后加上<code>协议名称</code>,中间以冒号<code>:</code>分隔即可实现协议;实现多个协议时,各协议之间用逗号<code>,</code>分隔,如下所示:</p>
<pre><code>struct SomeStructure: FirstProtocol, AnotherProtocol {
// 结构体内容
}
</code></pre><p>当某个类实现了协议,并含有父类时,应当把父类名放在所有的协议名称之前</p>
<pre><code>class SomeClass: SomeSuperClass, FirstProtocol, AnotherProtocol{
// 此处书写类的定义
</code></pre><p>当某个类含有<code>父类</code>的同时并实现了协议,应当把<code>父类</code>放在所有的<code>协议</code>之前,如下所示:</p>
<pre><code>class SomeClass: SomeSuperClass, FirstProtocol, AnotherProtocol {
// 类的内容
}
</code></pre><h2 id="-">属性要求</h2>
<p><code>协议</code>能够要求其<code>遵循者</code>必须拥有<strong>特定名称和类型</strong><code>实例属性(instance property)</code><code>类属性 (type property)</code>,也可以指定协议中的属性的<code>settable</code><code>gettable</code>,但它不要求<code>属性</code><code>存储型属性(stored property)</code>还是<code>计算型属性(calculate property)</code>.</p>
<p>当协议要求其中的<code>某个属性</code><code>gettable</code>时,即使实现了它的<code>setter</code>也不会出错. (<em>译者注:此小节术语较多,可参阅属性章节</em>).</p>
<p>属性通常被声明为变量,通过前置<code>var</code>关键字. 在属性声明后写上<code>{ get set }</code>指定属性为可读写的.<code>{ get }</code>用来描述属性为可读的.</p>
<p><code>协议</code>能够要求其<code>遵循者</code>必须含有一些<strong>特定名称和类型</strong><code>实例属性(instance property)</code><code>类属性 (type property)</code>,也能够要求属性的<code>(设置权限)settable</code><code>(访问权限)gettable</code>,但它不要求<code>属性</code><code>存储型属性(stored property)</code>还是<code>计算型属性(calculate property)</code>.</p>
<p>通常前置<code>var</code>关键字将属性声明为变量.在属性声明后写上<code>{ get set }</code>表示属性为可读写的.<code>{ get }</code>用来表示属性为可读的.即使你为可读的属性实现了<code>setter</code>方法,它也不会出错.</p>
<pre><code>protocol SomeProtocol {
var musBeSettable : Int { get set }
var doesNotNeedToBeSettable: Int { get }
}
</code></pre><p>当协议用来被类实现时,使用<code>class</code>关键字来说明该属性为类成员 ; 当协议被结构体或枚举实现时,则使用<code>static</code>关键字来说明</p>
</code></pre><p><code></code>来实现<code>协议</code>时,使用<code>class</code>关键字来表示该属性为类成员;用<code>结构体</code><code>枚举</code>实现<code>协议</code>时,则使用<code>static</code>关键字来表示:</p>
<pre><code>protocol AnotherProtocol {
class var someTypeProperty: Int { get set }
}
</code></pre><p>下边的协议包含了一个实例属性.</p>
<pre><code>protocol FullyNamed {
var fullName: string { get }
protocol FullyNamed {
var fullName: String { get }
}
</code></pre><p><code>FullyNamed</code> 定义了一个拥有 <code>fullName</code> 属性的协议. 该协议要求其 <code>遵循者</code> 必须有一个名为 <code>fullName</code>, 类型为 <code>String</code> 的可读属性.</p>
<p>下例是一个<code>遵循</code><code>FullyNamed</code> 协议的简单结构体</p>
</code></pre><p><code>FullyNamed</code>协议含有<code>fullName</code>属性.因此其<code>遵循者</code>必须有一个名为<code>fullName</code>,类型为<code>String</code>的可读属性.</p>
<pre><code>struct Person: FullyNamed{
var fullName: String
}
let john = Person(fullName: &quot;John Appleseed&quot;)
//john.fullName 为 &quot;John Appleseed&quot;
</code></pre><p>定义一个名为<code>Person</code>并实现了<code>FullyNamed</code>协议的结构体. 每一个<code>Person</code>实例都拥有一个<code>String</code>类型,名为<code>fullName</code><code>存储型属性</code>,它满足了<code>FullyNamed</code>协议的要求,也就是说 <code>Person</code>完整的遵循了该协议.(如果协议未被完整遵循,Swift编译时会报出错误). </p>
<p>下例是一个遵循<code>FullyNamed</code>协议的类:</p>
</code></pre><p><code>Person</code>结构体含有一个名为<code>fullName</code><code>存储型属性</code>,完整的<code>遵循</code>协议.(<em>协议未被完整遵循,编译时会报</em>). </p>
<p>如下所示,<code>Startship</code><code>遵循</code><code>FullyNamed</code>协议:</p>
<pre><code>class Starship: FullyNamed {
var prefix: String?
var name: String
@ -643,22 +641,22 @@ let john = Person(fullName: &quot;John Appleseed&quot;)
}
var ncc1701 = Starship(name: &quot;Enterprise&quot;, prefix: &quot;USS&quot;)
// ncc1701.fullName == &quot;USS Enterprise&quot;
</code></pre><p>类将<code>fullName</code>实现为<code>计算型只读属性</code>.它的每一个实例都有一个名为<code>name</code>的必备属性和一个名为<code>prefix</code>的可选属性. 当<code>prefix</code>存在时,将<code>prefix</code>插入到<code>name</code>之前来为<code>Starship</code>构建<code>fullName</code></p>
</code></pre><p><code>Starship</code>类将<code>fullName</code>实现为可读的<code>计算型属性</code>.它的每一个实例都有一个名为<code>name</code>的必备属性和一个名为<code>prefix</code>的可选属性. 当<code>prefix</code>存在时,将<code>prefix</code>插入到<code>name</code>之前来为<code>Starship</code>构建<code>fullName</code></p>
<h2 id="-">方法要求</h2>
<p><code>协议</code>可以要求其<code>遵循者</code>必备某些特定的<code>实例方法</code><code>类方法</code>. 这些方法作为<code>协议</code>的一部分,像普通的方法一样写在协议体中,但却不需要方法体.而且,协议中的方法同样支持可变参数. </p>
<p><code>协议</code>能够要求其<code>遵循者</code>必备某些特定的<code>实例方法</code><code>类方法</code>.协议方法的声明与普通方法声明相似,但它不需要<code>方法</code>内容.</p>
<blockquote>
<p>笔记: 协议中的<code>方法</code>的语法同普通<code>方法</code>一样,但是不支持<code>默认参数</code>. </p>
<p>笔记: 协议方法支持<code>变长参数(variadic parameter)</code>,不支持<code>默认参数(default parameter)</code>.</p>
</blockquote>
<p>在协议中定义<code>类方法</code><code>类属性</code>一样,只需在方法前加上<code>class</code>关键字; 当协议用于被<code>枚举</code><code>结构体</code>遵循时,<code>类方法</code>的关键字需要换为<code>static</code>:</p>
<p>前置<code>class</code>关键字表示协议中的成员为<code>类成员</code>;当协议用于被<code>枚举</code><code>结构体</code>遵循时,则使用<code>static</code>关键字. 如下所示:</p>
<pre><code>protocol SomeProtocol {
class func someTypeMethod()
}
</code></pre><p>下边是拥有一个实例方法的协议的例子</p>
<pre><code>protocol RandomNumberGenerator {
protocol RandomNumberGenerator {
func random() -&gt; Double
}
</code></pre><p><code>RandomNumberGenerator</code> 协议要求其<code>遵循者</code>必须拥有一个名为<code>random</code>, 返回值类型为<code>Double</code> 的实例方法. (这里假设随机数在 [0,1] 之间). 该协议只为生成随机数提供了一个统一的函数名称,而不去做具体的实现工作. </p>
<p>这里有一个名为<code>LinearCongruentialGenerator</code><code>遵循</code><code>RandomNumberGenerator</code>协议的类. 该类实现了名为 <em>linear congruential generator</em>(线性同余生成器) 的假随机数算法</p>
</code></pre><p><code>RandomNumberGenerator</code>协议要求其<code>遵循者</code>必须拥有一个名为<code>random</code>, 返回值类型为<code>Double</code>的实例方法. (我们假设随机数在[0,1]区间内).</p>
<p><code>LinearCongruentialGenerator</code><code>遵循</code><code>RandomNumberGenerator</code>协议,并提供了一个叫做<em>线性同余生成器(linear congruential generator)</em>的伪随机数算法.</p>
<pre><code>class LinearCongruentialGenerator: RandomNumberGenerator {
var lastRandom = 42.0
let m = 139968.0
@ -675,17 +673,17 @@ println(&quot;Here&#39;s a random number: \(generator.random())&quot;)
println(&quot;And another one: \(generator.random())&quot;)
// 输出 : &quot;And another one: 0.729023776863283&quot;
</code></pre><h2 id="-">突变方法要求</h2>
<p>有时不得不在方法中改变实例的所属的类型.在基于<code>Value Type</code>的实例方法(<em>译者注:指结构体和枚举中的方法</em>)的<code>func</code>前加上<code>mutating</code>关键字来表明该方法允许改变该实例和其属性的所属类型. 这一变过程在 [Modifyting Value Types from Within Instance Methods][1] 一节中有详细描述.</p>
<p>如果你打算在协议中定义一个能够改变实例所属类型的实例方法,只需要在方法前加上<code>mutating</code>关键字.使得结构体和枚举遵循该协议.(<em>译者注:类中的变量为 Reference Type ,可以轻易的改变实例及其属性的类型 . 而结构体和枚举中的变量都为 Value Type, 因此需要加上<code>mutating</code>关键字才能更改它们的所属类型</em>)</p>
<p>能在<code>方法</code><code>函数</code>内部改变实例类型的方法称为<code>突变方法</code>.在<code>值类型(Value Type)</code>(<em>译者注:指结构体和枚举</em>)中的<code>函数</code>加上<code>mutating</code>关键字来表示该函数允许改变该实例和其属性的类型. 这一变过程在<a href="1">Modifyting Value Types from Within Instance Methods</a>节中有详细描述.</p>
<p>(<em>译者注:类中的成员为<code>引用类型(Reference Type)</code>,可以方便的修改实例及其属性的值而无需改变类型;而<code>结构体</code><code>枚举</code>中的成员均为<code>值类型(Value Type)</code>,修改变量的值就相当于修改变量的类型,而<code>Swift</code>默认不允许修改类型,因此需要前置<code>mutating</code>关键字用来表示该<code>函数</code>中能够修改类型</em>)</p>
<blockquote>
<p>当协议的实例方法标记为<code>mutating</code>时,在结构体或枚举的实现该方法时中,<code>mutating</code>关键字是不必可少的;当使用类遵循该协议时,则不需要为这个实例方法前加 <code>mutating</code> 关键字.</p>
<p>注意: 用<code></code>实现协议中的<code>mutating</code>方法时,不用写<code>mutating</code>关键字;用<code>结构体</code>,<code>枚举</code>实现协议中的<code>mutating</code>方法时,必须写<code>mutating</code>关键字.</p>
</blockquote>
<p>下例定义了一个名为<code>Togglable</code>,含有一个<code>toggle</code>方法的协议.通过名称测,<code>toggle</code>方法应该是用来 <strong>切换或恢复</strong> 某个属性的状态使用的.<code>toggle</code>方法前含有<code>mutating</code>关键字,用以标识其可以更改其<code>遵循者</code>的实例及其属性的所属类型.</p>
<p>如下所示,<code>Togglable</code>协议含有<code>toggle</code>函数.根据函数名称测,<code>toggle</code>可能用于<strong>切换或恢复</strong>某个属性的状态.<code>mutating</code>关键字表示它为<code>突变方法</code>:</p>
<pre><code>protocol Togglable {
mutating func toggle()
}
</code></pre><p>如果你使用枚举或结构体来实现<code>Togglabl</code>协议时,必须在枚举或接头体的<code>toggle</code>方法前加上<code>mutating</code>关键字.</p>
<p>下例定义了一个名为<code>OnOffSwitch</code>枚举. 这个枚举可以切换<code>On</code>,<code>Off</code>两种状态. 该枚举中的 <code>toggle</code>含有<code>mutating</code>标记,用以匹配<code>Togglable</code>协议的方法要求:</p>
</code></pre><p>当使用<code>枚举</code><code>结构体</code>来实现<code>Togglabl</code>协议时,必须在<code>toggle</code>方法前加上<code>mutating</code>关键字.</p>
<p>如下所示,<code>OnOffSwitch</code>枚举<code>遵循</code><code>Togglable</code>协议,<code>On</code>,<code>Off</code>两个成员用于表示当前状态</p>
<pre><code>enum OnOffSwitch: Togglable {
case Off, On
mutating func toggle() {
@ -700,18 +698,17 @@ println(&quot;And another one: \(generator.random())&quot;)
var lightSwitch = OnOffSwitch.Off
lightSwitch.toggle()
//lightSwitch 现在的值为 .On
</code></pre><h2 id="-">协议作为类型</h2>
<p>尽管<code>协议</code>本身不实现任何功能,但你可以将它当做<code>类型</code>来使用.</p>
<p>包括: </p>
</code></pre><h2 id="-">协议类型</h2>
<p><code>协议</code>本身不实现任何功能,但你可以将它当做<code>类型</code>来使用.</p>
<p>使用场景: </p>
<ul>
<li>作为函数,方法或构造器中的参数类型,返回值类型</li>
<li>作为常量,变量,属性的类型</li>
<li>作为数组,字典或其他容器中的元素类型</li>
</ul>
<blockquote>
<p>Note: 协议是一种类型,因此你应该向其他类型那样(Int,Double,String),使用驼峰式写法来书写协议</p>
<p>注意: 协议类型应与其他类型(Int,Double,String)的写法相同,使用驼峰式</p>
</blockquote>
<p>这里有一个使用协议类型的例子:</p>
<pre><code>class Dice {
let sides: Int
let generator: RandomNumberGenerator
@ -724,11 +721,10 @@ lightSwitch.toggle()
}
}
</code></pre><p>这里定义了一个名为 <code>Dice</code>的类,用来代表桌游中的N个面的骰子.</p>
<p> <code>Dice</code>拥有名为<code>sides</code><code>generator</code>两个属性,前者用来表示骰子有几个面,后者用来为骰子提供一个随机数生成器</p>
<p><code>generator</code>是一个<code>RandomNumberGenerator</code>协议类型的属性.因此,你可以为它赋值任何<code>遵循</code>协议的类型.</p>
<p><code>Dice</code>也拥有一个<code>构造器(initializer)</code>用来设置它的初始状态.构造器中含有一个名为<code>generator</code>,类型为<code>RandomNumberGenerator</code>的形参.你可以在此传入任意遵循<code>RandomNumberGenerator</code>协议的类型.</p>
<p><code>roll</code>是一个用以返回骰子面值的实例方法.该方法先调用<code>generator</code><code>random</code>方法来创建一个 [0-1] 之间的随机数,然后使用这个随机数来生成骰子的面值. 这里的<code>generator</code> 被声明为采纳了<code>RandomNumberGenerator</code>协议,用以确保<code>random</code>方法能够被调用 </p>
<p>下例展示了一个使用<code>LinearCongruentialGenerator</code>实例作为随机数生成器的六面骰子</p>
<p> <code>Dice</code>含有<code>sides</code><code>generator</code>两个属性,前者用来表示骰子有几个面,后者为骰子提供一个随机数生成器.由于后者为<code>RandomNumberGenerator</code>的协议类型.所以它能够被赋值为任意<code>遵循</code>该协议的类型.</p>
<p>此外,使用<code>构造器(init)</code>来代替之前版本中的<code>setup</code>操作.构造器中含有一个名为<code>generator</code>,类型为<code>RandomNumberGenerator</code>的形参,使得它可以接收任意遵循<code>RandomNumberGenerator</code>协议的类型.</p>
<p><code>roll</code>方法用来模拟骰子的面值.它先使用<code>generator</code><code>random</code>方法来创建一个[0-1]区间内的随机数种子,然后加工这个随机数种子生成骰子的面值.</p>
<p>如下所示,<code>LinearCongruentialGenerator</code>的实例作为随机数生成器传入<code>Dice</code><code>构造器</code></p>
<pre><code>var d6 = Dice(sides: 6,generator: LinearCongruentialGenerator())
for _ in 1...5 {
println(&quot;Random dice roll is \(d6.roll())&quot;)
@ -739,11 +735,11 @@ for _ in 1...5 {
//Random dice roll is 4
//Random dice roll is 5
//Random dice roll is 4
</code></pre><h2 id="-">委托(代理)</h2>
<p>委托是一种设计模式(<em>译者注:想起了那年 UITableViewDelegate 中的奔跑,那是我逝去的Objective-C...</em>),它允许类或结构体将一些需要它们负责的功能或任务交由(委托)给其他的类型.</p>
<p>代理设计模式的实现很简单,首先定义一个<code>协议</code><code>封装</code>那些需要被委托的功能的<code>函数和方法</code>, 然后确保<code>遵循者</code>拥有这些被委托的<code>函数和方法</code>.
委托模式可以用来响应特定的动作,或接收外部数据源提供的数据而无需要知道外部数据源的类型.</p>
<p>边这个例子展示了两个基于骰子游戏的两个协议: </p>
</code></pre><h2 id="-">委托(代理)模式</h2>
<p>委托是一种设计模式(<em>译者注: 想起了那年 UITableViewDelegate 中的奔跑,那是我逝去的Objective-C...</em>),它允许<code></code><code>结构体</code>将一些需要它们负责的功能<code>交由(委托)</code>给其他的类型.</p>
<p>委托模式的实现很简单: 定义<code>协议</code><code>封装</code>那些需要被委托的<code>函数和方法</code>, 使<code>遵循者</code>拥有这些被委托的<code>函数和方法</code>.</p>
<p>委托模式可以用来响应特定的动作或接收外部数据源提供的数据,而无需要知道外部数据源的类型.</p>
<p>文是两个基于骰子游戏的协议: </p>
<pre><code>protocol DiceGame {
var dice: Dice { get }
func play()
@ -753,8 +749,8 @@ protocol DiceGameDelegate {
func game(game: DiceGame, didStartNewTurnWithDiceRoll diceRoll:Int)
func gameDidEnd(game: DiceGame)
}
</code></pre><p><code>DiceGame</code>协议可以被任何包含骰子的游戏采纳.<code>DiceGameDelegate</code>协议可以用来追踪<code>DiceGame</code>的游戏过程</p>
<p>下边是一个 <code>Snakes and Ladders</code> 游戏的新版本(<a href="2">Control Flow</a><em>含有关于该游戏的介绍</em>).新版本使用<code>Dice</code>中的骰子,实现<code>DiceGame</code><code>DiceGameDelegate</code>协议</p>
</code></pre><p><code>DiceGame</code>协议可以在任意含有骰子的游戏中实现,<code>DiceGameDelegate</code>协议可以用来追踪<code>DiceGame</code>的游戏过程</p>
<p>如下所示,<code>SnakesAndLadders</code><code>Snakes and Ladders</code>(译者注:<a href="2">Control Flow</a>章节有该游戏的详细介绍)游戏的新版本.新版本使用<code>Dice</code>作为骰子,并且实现<code>DiceGame</code><code>DiceGameDelegate</code>协议</p>
<pre><code>class SnakesAndLadders: DiceGame {
let finalSquare = 25
let dic = Dice(sides: 6, generator: LinearCongruentialGenerator())
@ -785,12 +781,13 @@ protocol DiceGameDelegate {
delegate?.gameDIdEnd(self)
}
}
</code></pre><p>更详细<code>Shakes and Ladders</code>游戏描述,请在 <a href="3">Control Flow -&gt; Break</a> 章节查看.<br>这个版本的游戏被包装到了名<code>SnakeAndLadders</code>并实现了<code>DiceGame</code>协议的类中. 该类含有一个可读的<code>dice</code>属性和一个<code>play</code>方法用来遵循协议.</p>
<p>游戏的初始化设置(<code>setup</code>)被为类的构造器(<code>init()</code>)来实现.所有的游戏逻辑被转移到了协议方法<code>play</code>中.</p>
<p>注意:<code>delegate</code> 被定义为遵循<code>DiceGameDelegate</code>协议的可选属性,因为委托并不是该游戏的必备条件.</p>
<p><code>DicegameDelegate</code> 提供了三个方法用来追踪游戏过程.被放置于游戏的逻辑中,即<code>play()</code>方法内.分别在游戏开始时,新一轮开始时,游戏结束时被调用.</p>
<p>因为<code>delegate</code>是一个遵循<code>DiceGameDelegate</code>的可选属性,因此在<code>play()</code>方法中使用了<code>可选链</code>来调用委托方法. 如果<code>delegate</code>属性为<code>nil</code>, 则委托调用<em>优雅的,不含错误的</em>失败.如果<code>delegate</code>不为<code>nil</code>, 则这些委托方法被调用,并且把<code>SnakesAndLadders</code>的这个实例当做参数一并传递</p>
<p>下边的这个例子展示了一个名为<code>DiceGameTracker</code>,实现<code>DiceGameDelegate</code>协议的类</p>
</code></pre><p>游戏<code>初始化设置(setup)</code><code>SnakesAndLadders</code>类的<code>构造器(initializer)</code>实现.所有的游戏逻辑被转移到了<code>play</code>方法.</p>
<blockquote>
<p>注意:因为<code>delegate</code>并不是该游戏的必备条件,<code>delegate</code>被定义为遵循<code>DiceGameDelegate</code>协议的可选属性</p>
</blockquote>
<p><code>DicegameDelegate</code>协议提供了三个方法用来追踪游戏过程.被放置于游戏的逻辑中,即<code>play()</code>方法内.分别在游戏开始时,新一轮开始时,游戏结束时被调用.</p>
<p>因为<code>delegate</code>是一个遵循<code>DiceGameDelegate</code>的可选属性,因此在<code>play()</code>方法中使用了<code>可选链</code>来调用委托方法. 若<code>delegate</code>属性为<code>nil</code>, 则委托调用<em>优雅地</em>失效.若<code>delegate</code>不为<code>nil</code>,则委托方法被调用</p>
<p>如下所示,<code>DiceGameTracker</code>遵循了<code>DiceGameDelegate</code>协议</p>
<pre><code>class DiceGameTracker: DiceGameDelegate {
var numberOfTurns = 0
func gameDidStart(game: DiceGame) {
@ -808,9 +805,9 @@ protocol DiceGameDelegate {
println(&quot;The game lasted for \(numberOfTurns) turns&quot;)
}
}
</code></pre><p><code>DiceGameTracker</code>实现了<code>DiceGameDelegate</code>协议中要求的全部方法.用来记录游戏已经进行的轮数. 当游戏开始时,<code>numberOfTurns</code>属性被赋值为0; 在每新一轮中递加; 游戏结束后,输出打印游戏的总轮数.</p>
<p><code>gameDidStart</code>使用<code>game</code>参数来打印游戏的一些介绍信息.<code>game</code>的类型是<code>DiceGame</code>而不是 <code>SnakeAndLadders</code>, 因此<code>gameDidStart</code>只能访问和使用<code>DiceGame</code>协议中的成员. 但是仍然可以使用类型转换来访问其实例. 在<code>gameDidStart</code>中,当<code>game</code><code>SnakesAndLadders</code>的实例时,会打印出适当的信息. 因为<code>game</code>是被视为遵循了<code>DiceGame</code>协议的属性,也就是说它拥有<code>dice</code>属性,所以<code>gameDidStart</code>方法可以访问和打印<code>dice</code><code>sides</code>属性,而无需知道这是一场什么游戏....</p>
<p>这是<code>DiceGameTracker</code>的运行实例:</p>
</code></pre><p><code>DiceGameTracker</code>实现了<code>DiceGameDelegate</code>协议的方法要求,用来记录游戏已经进行的轮数. 当游戏开始时,<code>numberOfTurns</code>属性被赋值为0; 在每新一轮中递加; 游戏结束后,输出打印游戏的总轮数.</p>
<p><code>gameDidStart</code>方法从<code>game</code>参数获取游戏信息并输出.<code>game</code>在方法中被当做<code>DiceGame</code>类型而不是<code>SnakeAndLadders</code>类型,所以方法中只能访问<code>DiceGame</code>协议中的成员.</p>
<p><code>DiceGameTracker</code>的运行情况,如下所示:</p>
<pre><code>“let tracker = DiceGameTracker()
let game = SnakesAndLadders()
game.delegate = tracker
@ -822,26 +819,26 @@ game.play()
// Rolled a 4
// Rolled a 5
// The game lasted for 4 turns”
</code></pre><h2 id="-extension-">在延展(Extension)中添加协议成员</h2>
<p>使无法修改源代码,依然可以通过<code>展(Extension)</code>来扩已存在类型(<em>译者注: 类,结构体,枚举等</em>).<code></code>可以为已存在的类型添加属性,方法,下标,协议等成员. 详情请在<a href="4"></a>章节中查看.</p>
</code></pre><h2 id="-">在扩展中添加协议成员</h2>
<p>便无法修改源代码,依然可以通过<code>展(Extension)</code>来扩已存在类型(<em>译者注: 类,结构体,枚举等</em>).<code></code>可以为已存在的类型添加<code>属性</code>,<code>方法</code>,<code>下标</code>,<code>协议</code>等成员.详情请在<a href="4"></a>章节中查看.</p>
<blockquote>
<p>笔记: 通过延展为已存在的类型增加协议时,该类型的实例会自动添加协议中的方法</p>
<p>注意: 通过<code>扩展</code>为已存在的类型<code>遵循</code>协议时,该类型的所有实例也会随之添加协议中的方法</p>
</blockquote>
<p>下例中<code>TextRepresentable</code>协议含有一个<code>asText</code> 方法,可以被任何类型<code>遵循</code></p>
<p><code>TextRepresentable</code>协议含有一个<code>asText</code>,如下所示:</p>
<pre><code>protocol TextRepresentable {
func asText() -&gt; String
}
</code></pre><p>通过延展为为上一节中的<code>Dice</code>实现并遵循<code>TextRepresentable</code>协议</p>
</code></pre><p>通过<code>扩展</code>为上一节中提到<code>Dice</code>类遵循<code>TextRepresentable</code>协议</p>
<pre><code>extension Dice: TextRepresentable {
cun asText() -&gt; String {
return &quot;A \(sides)-sided dice&quot;
}
}
</code></pre><p><code>Dice</code>类型的实例现在可以被视为<code>TextRepresentable</code>类型:</p>
</code></pre><p>从现在起,<code>Dice</code>类型的实例可被当作<code>TextRepresentable</code>类型:</p>
<pre><code>let d12 = Dice(sides: 12,generator: LinearCongruentialGenerator())
println(d12.asText())
// 输出 &quot;A 12-sided dice&quot;
</code></pre><p><code>SnakesAndLadders</code> 类也可通过<code></code>来遵循协议:</p>
</code></pre><p><code>SnakesAndLadders</code>类也可通过<code></code>的方式来遵循协议:</p>
<pre><code>extension SnakeAndLadders: TextRepresentable {
func asText() -&gt; String {
return &quot;A game of Snakes and Ladders with \(finalSquare) squares&quot;
@ -849,8 +846,8 @@ println(d12.asText())
}
println(game.asText())
// 输出 &quot;A game of Snakes and Ladders with 25 squares&quot;
</code></pre><h2 id="-">通过延展声明协议</h2>
<p>如果一个类型已经实现了协议中的所有要求,却没有声明时,可以通过声明空<code></code>采纳协议:</p>
</code></pre><h2 id="-">通过延展补充协议声明</h2>
<p>一个类型已经实现了协议中的所有要求,却没有声明时,可以通过<code></code>补充协议声明:</p>
<pre><code>struct Hamster {
var name: String
func asText() -&gt; String {
@ -858,36 +855,36 @@ println(game.asText())
}
}
extension Hamster: TextRepresentabl {}
</code></pre><p>现在开始,<code>Hamster</code>的实例可以被当做<code>TextRepresentable</code>类型使用</p>
</code></pre><p>现在,<code>Hamster</code>的实例可以作为<code>TextRepresentable</code>类型使用</p>
<pre><code>let simonTheHamster = Hamster(name: &quot;Simon&quot;)
let somethingTextRepresentable: TextRepresentabl = simonTheHamester
println(somethingTextRepresentable.asText())
// 输出 &quot;A hamster named Simon&quot;
</code></pre><blockquote>
<p>注意: 类型不会因为满足了协议而直接改变,你必须为它做出明显的实现协议声明</p>
<p>注意: 即时满足了协议的所有要求,类型也不会自动转变,因此你必须为它做出明显的协议声明</p>
</blockquote>
<h2 id="-">集合中的协议类型</h2>
<p>协议类型可以被集合使用,表示集合中的元素均为协议类型:</p>
<pre><code>let things: TextRepresentable[] = [game,d12,simoTheHamster]
</code></pre><p><code>things</code>数组可以被直接遍历,并调用其中元素的<code>asText()</code>函数:</p>
</code></pre><p>如下所示,<code>things</code>数组可以被直接遍历,并调用其中元素的<code>asText()</code>函数:</p>
<pre><code>for thing in things {
println(thing.asText())
}
// A game of Snakes and Ladders with 25 squares
// A 12-sided dice
// A hamster named Simon
</code></pre><p>上文代码中,<code>thing</code>认为<code>TextRepresentable</code>类型而不是<code>Dice</code>,<code>DiceGame</code>,<code>Hamster</code>等类型.因此,可以在循环中调用它们的<code>asText</code>方法</p>
</code></pre><p><code>thing</code>当做<code>TextRepresentable</code>类型而不是<code>Dice</code>,<code>DiceGame</code>,<code>Hamster</code>等类型.因此能且仅能调用<code>asText</code>方法</p>
<h2 id="-">协议的继承</h2>
<p>协议可以通过继承一个或多个其他协议.继承协议的语法和继承类的语法相似,多个协议间用逗号<code>,</code>分隔</p>
<p>协议能够继承一多个其他协议.语法与类的继承相似,多个协议间用逗号<code>,</code>分隔</p>
<pre><code>protocol InheritingProtocol: SomeProtocol, AnotherProtocol {
// 协议定义
}
</code></pre><p>下边是一个继承了<code>TextRepresentable</code>协议</p>
</code></pre><p>如下所示,<code>PrettyTextRepresentable</code>协议继承了<code>TextRepresentable</code>协议</p>
<pre><code>protocol PrettyTextRepresentable: TextRepresentable {
func asPrettyText() -&gt; String
}
</code></pre><p><code>PrettyTextRepresentable</code>协议继承自<code>TextRepresentable</code>协议.任何实现<code>PrettyTextRepresentable</code>协议的类型,也需要<code>遵循</code>TextRepresentable`协议.</p>
<p>用延展<code>SnakesAndLadders</code>遵循<code>PrettyTextRepresentable</code>协议:</p>
</code></pre><p><code>遵循``PrettyTextRepresentable</code>协议的同时,也需要<code>遵循</code>TextRepresentable`协议.</p>
<p>如下所示,用<code>扩展</code><code>SnakesAndLadders</code>遵循<code>PrettyTextRepresentable</code>协议:</p>
<pre><code>extension SnakesAndLadders: PrettyTextRepresentable {
func asPrettyText() -&gt; String {
var output = asText() + &quot;:\n&quot;
@ -904,18 +901,18 @@ println(somethingTextRepresentable.asText())
return output
}
}
</code></pre><p>上边的延展为<code>SnakesAndLadders</code>遵循了<code>PrettyTextRepresentabel</code>协议.<code>for in</code>中迭代出了<code>board</code>数组中的每一个元素:</p>
</code></pre><p><code>for in</code>中迭代出了<code>board</code>数组中的每一个元素:</p>
<ul>
<li>当数组中元素的值大于0时,用<code></code>表示</li>
<li>当数组中元素的值小于0时,用<code></code>表示</li>
<li>当数组中元素的值等于0时,用<code></code>表示</li>
<li>数组中迭代出的元素的值大于0时,用<code></code>表示</li>
<li>数组中迭代出的元素的值小于0时,用<code></code>表示</li>
<li>数组中迭代出的元素的值等于0时,用<code></code>表示</li>
</ul>
<p>任意<code>SankesAndLadders</code>的实例都可以使用<code>asPrettyText()</code>方法.</p>
<pre><code>println(game.asPrettyText())
// A game of Snakes and Ladders with 25 squares:
// ○ ○ ▲ ○ ○ ▲ ○ ○ ▲ ▲ ○ ○ ○ ▼ ○ ○ ○ ○ ▼ ○ ○ ▼ ○ ▼ ○
</code></pre><h2 id="-">协议合成</h2>
<p>一个协议可由多个协议组成,称为<code>协议合成(protocol composition)</code>,采用<code>protocol&lt;SomeProtocol, AnotherProtocol&gt;</code>这样的语法.当有多个协议时,中间以<code>,</code>分隔.</p>
<p>一个协议可由多个协议采用<code>protocol&lt;SomeProtocol, AnotherProtocol&gt;</code>这样的格式进行组合,称为<code>协议合成(protocol composition)</code>.</p>
<p>举个栗子:</p>
<pre><code>protocol Named {
var name: String { get }
@ -933,49 +930,48 @@ println(&quot;Happy birthday \(celebrator.name) - you&#39;re \(celebrator.age)!&
let birthdayPerson = Person(name: &quot;Malcolm&quot;, age: 21)
wishHappyBirthday(birthdayPerson)
// 输出 &quot;Happy birthday Malcolm - you&#39;re 21!
</code></pre><p>上例中,<code>Named</code>协议中含有<code>String</code>类型的<code>name</code>属性;<code>Aged</code>协议中含有<code>Int</code>类型的<code>age</code>属性.<code>Person</code>结构体<code>遵循</code>了这两个协议.</p>
<p>此外还定义了<code>wishHappyBirthday</code>函数,该函数的形参<code>celebrator</code>的类型为<code>protocol&lt;Named,Aged&gt;</code>,也就是说可以接受任意<code>遵循</code>这两个协议的<code>类型</code>.</p>
</code></pre><p><code>Named</code>协议包含<code>String</code>类型的<code>name</code>属性;<code>Aged</code>协议包含<code>Int</code>类型的<code>age</code>属性.<code>Person</code>结构体<code>遵循</code>了这两个协议.</p>
<p><code>wishHappyBirthday</code>函数的形参<code>celebrator</code>的类型为<code>protocol&lt;Named,Aged&gt;</code>.可以传入任意<code>遵循</code>这两个协议的类型的实例</p>
<blockquote>
<p>笔记: <code>协议合成</code>并不会生成一个新协议,而是将多个协议合成为一个临时的协议.</p>
<p>注意: <code>协议合成</code>并不会生成一个新协议类型,而是将多个协议合成为一个临时的协议,超出范围后立即失效.</p>
</blockquote>
<h2 id="-">检验协议的一致性</h2>
<p>使用<code>is</code><code>as</code>可以检验协议一致性,也可以将协议转换为特定的其他协议类型.检验与转换的语法和之前相同(<em>详情查看<a href="5">Typy Casting章节</a></em>):</p>
<p>使用<code>is</code>检验协议一致性,使用<code>as</code>将协议类型<code>向下转换(downcast)</code>的其他协议类型.检验与转换的语法和之前相同(<em>详情查看<a href="5">Typy Casting章节</a></em>):</p>
<ul>
<li><code>is</code>操作符用来检查实例是否<code>遵循</code>了某个<code>协议</code>. </li>
<li><code>as?</code>返回一个可选值,当实例<code>遵循</code>协议时,返回该协议类型;否则返回<code>nil</code></li>
<li><p><code>as</code>可以用来强制向下转型.</p>
<li><p><code>as</code>用以强制向下转型. </p>
<p> @objc protocol HasArea {</p>
<pre><code> var area: Double { get }
</code></pre><p> }</p>
</li>
</ul>
<blockquote>
<p>笔记: <code>@objc</code>用来表示协议是可选的,也可以用来表示暴露给<code>Objective-C</code>的代码,<em>[Using Siwft with Cocoa and Objectivei-c]</em>(6)一节中有详细介绍.
<code>@objc</code>型协议只对<code></code>有效,因此只能在<code></code>中检查协议的一致性.</p>
<p>注意: <code>@objc</code>用来表示协议是可选的,也可以用来表示暴露给<code>Objective-C</code>的代码,此外,<code>@objc</code>型协议只对<code></code>有效,因此只能在<code></code>中检查协议的一致性.详情查看<em><a href="6">Using Siwft with Cocoa and Objectivei-c</a></em>.</p>
</blockquote>
<pre><code>class Circle: HasArea {
let pi = 3.1415927
var radius: Double
var area: Double { return pi * radius * radius }
init(radius: Double) { self.radius = radius }
let pi = 3.1415927
var radius: Double
var area: Double { return pi * radius * radius }
init(radius: Double) { self.radius = radius }
}
class Country: HasArea {
var area: Double
init(area: Double) { self.area = area }
var area: Double
init(area: Double) { self.area = area }
}
</code></pre><p><code>Circle</code><code>Country</code>都遵循了<code>HasArea</code>协议,前者把<code>area</code>写为<code>计算型属性</code>,后者则把<code>area</code>写为<code>存储型属性</code></p>
<p>下边是一个没事实现<code>HasArea</code>协议的<code>Animal</code>类:</p>
<p>如下所示,Animal类没有实现任何协议</p>
<pre><code>class Animal {
var legs: Int
init(legs: Int) { self.legs = legs }
}
</code></pre><p><code>Circle,Country,Animal</code>并没有一个相同的基类,可以使<code>AnyObject</code>类型的数组来装在他们的实例:</p>
</code></pre><p><code>Circle,Country,Animal</code>并没有一个相同的基类,所以采<code>AnyObject</code>类型的数组来装在他们的实例,如下所示:</p>
<pre><code>let objects: AnyObject[] = [
Circle(radius: 2.0),
Country(area: 243_610),
Animal(legs: 4)
]
</code></pre><p>在迭代时可以检查<code>object</code>数组的元素是否<code>遵循</code><code>HasArea</code>协议:</p>
</code></pre><p>如下所示,在迭代时检查<code>object</code>数组的元素是否<code>遵循</code><code>HasArea</code>协议:</p>
<pre><code>for object in objects {
if let objectWithArea = object as? HasArea {
println(&quot;Area is \(objectWithArea.area)&quot;)
@ -987,24 +983,24 @@ init(area: Double) { self.area = area }
// Area is 243610.0
// Something that doesn&#39;t have an area
</code></pre><p>当数组中的元素遵循<code>HasArea</code>协议时,通过<code>as?</code>操作符将其<code>可选绑定(optional binding)</code><code>objectWithArea</code>常量上.</p>
<p><code>objects</code>数组中元素的类型并不会改变,但是当它们被赋值给<code>objectWithArea</code>时只被视为<code>HasArea</code>类型,并且只有<code>area</code>属性可以被访问.</p>
<p><code>objects</code>数组中元素的类型并不会因为<code>向下转型</code>改变,当它们被赋值给<code>objectWithArea</code>时只被视为<code>HasArea</code>类型,因此只有<code>area</code>属性能够被访问.</p>
<h2 id="-">可选协议要求</h2>
<p>可选协议含有可选成员,其<code>遵循者</code>可以选择是否实现这些成员.在协议中使用<code>@optional</code>关键字作为前缀来定义可选成员.</p>
<p>可选协议在调用时使用<code>可选链</code>,详细内容在<a href="7">Optional Chaning</a>章节中查看.</p>
<p><code>someOptionalMethod?(someArgument)</code>一样,你可以在可选方法名称后加上<code>?</code>来检查该方法是否被实现.<code>可选方法</code><code>可选属性</code>都会返回一个<code>可选值(optional value)</code>,当其不可访问时,<code>?</code>之后语句不会执行,并返回<code>nil</code></p>
<blockquote>
<p>笔记: 可选协议只能在含有<code>@objc</code>前缀的协议中生效.且<code>@objc</code>的协议只能被<code></code>遵循</p>
<p>注意: 可选协议只能在含有<code>@objc</code>前缀的协议中生效.且<code>@objc</code>的协议只能被<code></code>遵循</p>
</blockquote>
<p>下问定义了整型计数器<code>Counter</code>,该类使用外部的数据源来提供<code>增量值(increment amount)</code>. 数据源定义为<code>CounterDataSource</code>类型的协议,如下所示</p>
<p><code>Counter</code>使用<code>CounterDataSource</code>类型的外部数据源来提供<code>增量值(increment amount)</code>,如下所示:</p>
<pre><code>@objc protocol CounterDataSource {
@optional func incrementForCount(count: Int) -&gt; Int
@optional var fixedIncrement: Int { get }
}
</code></pre><p><code>CounterDataSource</code>含有<code>incrementForCount</code><code>可选方法</code><code>fiexdIncrement</code><code>可选属性</code>.</p>
<blockquote>
<p>笔记: <code>CounterDataSource</code>中的属性和方法都是可选的,因此可以不提供所需要的属性或方法来实现它.尽管技术上允许,但这并不提倡这样.</p>
<p>注意: <code>CounterDataSource</code>中的属性和方法都是可选的,因此可以在类中声明但不实现这些成员,尽管技术上允许这样做,不过最好不要这样.</p>
</blockquote>
<p><code>Counter</code>的定义在下边,它含有一个名为<code>dataSource</code>,<code>CounterDataSource?</code>类型的可选属性:</p>
<p><code>Counter</code>含有<code>CounterDataSource?</code>类型的可选属性<code>dataSource</code>,如下所示:</p>
<pre><code>@objc class Counter {
var count = 0
var dataSource: CounterDataSource?
@ -1024,11 +1020,11 @@ init(area: Double) { self.area = area }
</ol>
<p>在调用<code>incrementForCount</code>方法后,<code>Int</code><code>可选值</code>通过<code>可选绑定(optional binding)</code>自动拆包并赋值给常量<code>amount</code>.</p>
<p><code>incrementForCount</code>不能被调用时,尝试使用<code>可选属性``fixedIncrement</code>来代替.</p>
<p>下边是一个简单的<code>CounterDataSource</code>协议的实现.</p>
<p><code>ThreeSource</code>实现了<code>CounterDataSource</code>协议,如下所示:</p>
<pre><code>class ThreeSource: CounterDataSource {
let fixedIncrement = 3
}
</code></pre><p>可以使用<code>ThreeSource</code>作为数据源开实例化一个<code>Counter</code>:</p>
</code></pre><p>使用<code>ThreeSource</code>作为数据源开实例化一个<code>Counter</code>:</p>
<pre><code>var counter = Counter()
counter.dataSource = ThreeSource()
for _ in 1...4 {
@ -1039,7 +1035,7 @@ for _ in 1...4 {
// 6
// 9
// 12
</code></pre><p>下边是一个更为复杂的数据源实现:</p>
</code></pre><p><code>TowardsZeroSource</code>实现了<code>CounterDataSource</code>协议中的<code>incrementForCount</code>方法,如下所示:</p>
<pre><code>class TowardsZeroSource: CounterDataSource {
func incrementForCount(count: Int) -&gt; Int {
if count == 0 {
@ -1051,8 +1047,7 @@ func incrementForCount(count: Int) -&gt; Int {
}
}
}
</code></pre><p><code>TowardZeroSource</code>类实现了<code>CounterDataSource</code><code>可选方法``incrementForCount</code>.</p>
<p>下边是执行的代码:</p>
</code></pre><p>下边是执行的代码:</p>
<pre><code>counter.count = -4
counter.dataSource = TowardsZeroSource()
for _ in 1...5 {

View File

@ -46,7 +46,7 @@
<div class="book" data-level="2.22" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="2.22" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_45">
<section class="normal" id="section-gitbook_42">
<h1 id="-">泛型</h1>
<hr>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="2.23" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="2.23" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="2" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="2" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_49">
<section class="normal" id="section-gitbook_46">
<h1 id="swift-">Swift 教程</h1>
<p>本章介绍了 Swift 的各种特性及其使用方法,是全书的核心部分。</p>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="3.1" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="3.1" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_51">
<section class="normal" id="section-gitbook_48">
<h1 id="-">关于语言附注</h1>
<p>本书的这一节描述了Swift编程语言的形式语法。这里描述的语法是为了帮助您更详细的了解该语言而不是让您直接实现一个解析器或编译器。</p>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="3.2" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="3.2" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_56">
<section class="normal" id="section-gitbook_53">
<h1 id="-">语法结构</h1>
<p>本页包含内容:</p>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="3.3" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="3.3" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_52">
<section class="normal" id="section-gitbook_49">
<h1 id="-types-">类型Types</h1>
<hr>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="3.4" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="3.4" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="3.6" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="3.6" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="3.7" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="3.7" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_50">
<section class="normal" id="section-gitbook_47">
<h1 id="-">特性</h1>
<p>特性提供了关于声明和类型的更多信息。在Swift中有两类特性用于修饰声明的以及用于修饰类型的。例如<code>required</code>特性,当应用于一个类的指定或便利初始化器声明时,表明它的每个子类都必须实现那个初始化器。再比如<code>noreturn</code>特性,当应用于函数或方法类型时,表明该函数或方法不会返回到它的调用者。</p>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="3.8" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="3.8" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="3.9" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="3.9" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_58">
<section class="normal" id="section-gitbook_55">
<h1 id="-">泛型参数</h1>
<hr>

File diff suppressed because one or more lines are too long

View File

@ -46,7 +46,7 @@
<div class="book" data-level="3.5" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="3.5" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -587,7 +587,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_61">
<section class="normal" id="section-gitbook_59">
<h1 id="-">语句</h1>
<p>在 Swift 中有两种类型的语句简单语句和控制流语句。简单语句是最常见的用于构造表达式和声明。控制流语句则用于控制程序执行的流程Swift 中有三种类型的控制流语句:循环语句、分支语句和控制传递语句。</p>

View File

@ -46,7 +46,7 @@
<div class="book" data-level="3" data-basepath=".." data-revision="1402328527093">
<div class="book" data-level="3" data-basepath=".." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>

View File

@ -44,7 +44,7 @@
<div class="book" data-level="0" data-basepath="." data-revision="1402328527093">
<div class="book" data-level="0" data-basepath="." data-revision="1402373659943">
<div class="book-header">
<!-- Actions Left -->
<a href="#" class="btn pull-left toggle-summary" aria-label="Toggle summary"><i class="fa fa-align-justify"></i></a>
@ -585,7 +585,7 @@
<div class="page-inner">
<section class="normal" id="section-gitbook_8">
<section class="normal" id="section-gitbook_5">
<h1 id="swift-">Swift 编程语言</h1>
<p>Swift 是苹果在 WWDC 2014 上发布的一款全新的编程语言,本书译自苹果官方的 Swift 教程《The Swift Programming Language》。</p>

View File

@ -1,5 +1,5 @@
CACHE MANIFEST
# Revision 1402328527096
# Revision 1402373659944
CACHE:
index.html
@ -39,8 +39,8 @@ chapter3/02_Lexical_Structure.html
chapter3/07_Patterns.html
chapter3/08_Generic_Parameters_and_Arguments.html
chapter3/09_Summary_of_the_Grammar.html
chapter3/10_Statements.html
chapter3/chapter3.html
chapter3/10_Statements.html
gitbook/app.js
gitbook/fonts/anonymouspro/400.woff
gitbook/fonts/anonymouspro/400i.woff

File diff suppressed because one or more lines are too long