Swift基础教程(第2版)(txt+pdf+epub+mobi电子书下载)


发布时间:2020-06-01 06:57:09

点击下载

作者:皮特(Boisy G. Pitre)

出版社:人民邮电出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

Swift基础教程(第2版)

Swift基础教程(第2版)试读:

前言

欢迎阅读本书!Swift是苹果公司新推出的用于开发iOS和Mac OS X应用程序的语言,注定将成为移动和桌面领域首屈一指的计算机语言。作为一门新的计算机语言,Swift犹如闪闪发亮的新车般充满诱惑:谁都想凑近瞧一瞧,踢踢它的轮胎,开着它去兜风。这可能就是你阅读本书的原因:你听说过Swift,并决定一探究竟。

Swift是一门易学易用的语言,这无疑是优点,相比于其前身Objective-C来说尤其如此,Objective-C虽然功能强大,但学习起来更难。长期以来,苹果公司一直将Objective-C作为其平台的软件开发语言,但随着Swift的面世,情况正在发生变化。针对的读者

本书是为初学者编写的。鉴于Swift面世时间极短,从某种意义上说我们都是初学者。然而,对很多人来说,Swift是其学习的第一门或第二门语言,他们大多未接触过Objective-C以及C和C++等相关语言。

读者最好对计算机语言有一定认识和经验,但本书也适合有足够学习欲望的新手。经验较丰富的开发人员可能发现前几章属于复习材料,类似休闲读物,因为其中介绍的概念在众多计算机语言中都有,但对于初学者来说,这些概念必须介绍。如何使用本书

与其他同类图书一样,本书也最适合从头到尾地按顺序阅读,因为后续章节要求你已经掌握之前介绍的知识。然而,几乎每章的示例代码都自成一体。

本书篇幅适中,既涵盖了丰富的内容,又不会让读者不堪重负。书中包含大量的屏幕截图,让初学者能够全面了解Swift和Xcode工具集。你将如何学习

学习Swift的最佳方式是使用它,而本书包含大量的代码和示例,始终将使用Swift作为重点。

每章都包含基于其中的概念编写的代码。Swift提供了两种交互式环境,可供你用来测试概念以及加深对Swift本身的认识——REPL和游乐场(playground)。在本书的第二部分,你将创建两个简单而完备的应用程序:一个运行于Mac OS X系统下的贷款计算器和一个iOS记忆游戏;在最后一章,你将研究一个完整2D游戏的源代码,这个游戏使用了Apple的多种游戏开发技术。

对Swift概念的介绍贯穿本书始终,这包括类、函数、闭包等。建议你不要着急,慢慢地阅读每一章,并在必要时反复阅读,然后再进入下一章。

www.peachpit.com/swiftbeginners2提供了本书源代码,你可下载每章的源代码。直接下载代码可节省大量的输入时间,但我深信应手工输入,这样做可获得仅阅读本书并依赖于下载的代码无法获得的洞见和认识。请花点时间输入所有的代码示例。

为清晰起见,代码和类名语言结构使用了等宽字体。 1> let candyJar = ["Peppermints", "Gooey Bears", "Happy Ranchers"]candyJar: [String] = 3 values { [0] = "Peppermints" [1] = "Gooey Bears" [2] = "Happy Ranchers"} 2>

对于REPL显示的错误消息,使用了粗体。 8> x = yrepl.swift:8:5: error: cannot assign a value of type 'Double' to a value of type 'Int'x = y ^ 8>“注意”提供了有关当前介绍的主题的额外信息。注意 字典键并不一定是按字母顺序排列的,Swift总是采用可最大限度地提高检索和访问效率的顺序来排列它们。你将学到哪些知识

本书的终极目标是,介绍如何使用Swift代码来表达思想。等阅读到本书最后一页时,你将对Swift的功能有深入认识,并具备开始编写应用程序所需的技能。本书第二部分提供了iOS和Mac OS X应用程序示例。

本书并非包罗万象的Swift编程语言综合指南,要全面了解Swift,苹果公司的官方文档是最佳的资源。本书的重点是Swift语言本身,但为帮助理解示例,简要地介绍了相关的Cocoa和CocoaTouch框架。欢迎来到Swift世界

Swift是苹果公司新推出的一款有趣而易学的计算机语言。掌握本书介绍的知识后,你将能够开始编写iOS和Mac OS X应用程序。要开始学习Swift,Xcode集成开发环境(IDE,Integrated Development Environment)是必须有的主要工具。Xcode提供了Swift编译器以及iOS和Mac OS X软件开发包(SDK,Software Development Kit),这些SDK包含为你开发的应用程序提供支持的基础设施。技术

在这次Swift学习之旅中,你将领略下面的风景。Swift 2

Swift 2是你将在本书中学习的语言,这是一款从头打造的现代语言,功能强大且易于学习。苹果公司已将其作为日益增长的iOS、watchOS、tvOS和Mac OS X应用程序开发语言。Xcode 7

Xcode 7是苹果公司首要的应用程序开发环境,提供了编辑器、调试器、项目管理器和编译器,其中编译器用于将Swift代码转换为能够运行的代码。Xcode可从Apple Mac App Store下载。LLVM

在Xcode中,LLVM在幕后工作,这种编译器技术让Swift语言变得优雅,并将Swift代码转换为Apple设备处理器能够运行的机器码。REPL

REPL(Read-Eval-Print-Loop)是一个命令行工具,可用于快速尝试Swift代码。在Mac OS X中,可在应用程序Terminal中运行它。

REPL游乐场

Xcode游乐场提供了交互性和实时的结果,在学习Swift时非常适合用来尝试代码。

游乐场

游乐场第一部分基础知识

无论学习什么新东西,都得从基础开始,Swift 无论学习什么新东西,都得从基础开始,Swift 语言也不例外。Swift 是一款卓越的新语言,这部分介绍了使用它编写一流应用程序所需的全部知识!

本部分内容● 第 1 章 Swift 简介● 第 2 章 使用集合● 第 3 章 流程控制● 第 4 章 编写函数和闭包● 第 5 章 使用类和结构组织代码● 第 6 章 使用协议和扩展进行规范化第1章Swift简介

欢迎来到Swift这个美丽的新世界。Swift是在2014年苹果全球开发者大会上推出的,仅仅一年后,它就成了一门功能强大的新编程语言。由于苹果的倡导和开发人员的积极响应,Swift被广泛采纳,成了开发iOS、watchOS和Mac应用程序的主流语言。Swift不但功能强大,还简单易学,你在不知不觉间就能编写出简单应用。

Swift提供了一些编写代码的新方式,比功能强大而著名的前身Objective-C容易理解得多。Swift向开发人员提供了全新而有趣的方式表达,其功能学习起来也很有趣。

Swift作为计算机语言虽已推出一年之久,但依然是一门新语言,苹果公司很可能对其进行修改和增补。从未有一种计算机语言像Swift这样,在即将修改和修订前能获得如此高的曝光度和采纳度,这都要归功于Swift的创新带来的刺激。1.1 革命性的改良

语言是分享、交流和传达信息的工具,人类通过它向朋友、家人和同事表达自己的意图。与计算机系统交流也需要通过计算机语言。

与人类的语言一样,计算机语言也非新鲜事物,事实上,它们以这样或那样的形式存在了很多年。计算机语言的目的始终是让人类能够与计算机交流,命令它执行特定的操作。

不断发展变化的是计算机语言本身。早期的计算机开拓者意识到,以0和1的方式向计算机发指令既繁琐又容易出错。一路上人们始终在不断努力,旨在在语言语法的丰富性和处理与解读它所需的计算能力之间寻求平衡,最终诸如C和C++语言在争夺现代计算机应用程序通用语言之战中取得了胜利。

在C和C++被广泛接受,得以用于主要的计算平台的同时,苹果携Objective-C给这场盛宴带来了清新之风。Objective-C是一款建立在C语言基础之上的面向对象语言。苹果生态系统由Macintosh计算机和iOS设备构成,在为该生态系统开发应用程序中,Objective-C多年来始终发挥着中流砥柱的作用。

Objective-C虽然功能强大而优雅,但也存在着其前身——C语言遗留下来的包袱。对于熟悉C语言的人来说,这根本就不是什么问题,但近年来大量新开发人员进入Mac和iOS平台,他们渴望更容易理解和使用的新语言。

为满足这种需求,并降低进入门槛,苹果公司推出了Swift。使用它编写应用程序容易得多,向应用程序发出指令也更加简便。1.2 准备工作

你可能会问,要学习Swift需要满足哪些条件呢?实际上,开始阅读本书就迈出了学习Swift的第一步。学习新的计算机语言可能令人望而却步,这正是笔者为Swift初学者编写本书的原因所在。如果你是Swift新手,本书正是为你编写的;如果你从未使用过C、C++和Objective-C,本书也适合你阅读。即便你是经验丰富的开发人员,熟悉前面提及的各种语言,本书也可帮助你快速掌握Swift。

虽然并非绝对必要,但熟悉或大致了解其他编程语言对阅读本书很有帮助。本书不介绍如何编程,也不提供有关软件开发的基本知识,而假定你对计算机语言的基本概念有一定认识,因此你必须对计算机语言有所了解。

虽然如此,本书将向你提供尽可能多的帮助:详尽地解释新引入的术语,并对概念做尽可能清晰的阐述。1.2.1 专业工具

至此,你做好了学习Swift的心理准备。这很好!但首先得将学习用品准备妥当。回想一下上小学时的情形吧,开学前父母都会收到所需学习用品清单:笔记本、剪刀、美术纸、胶水、2号铅笔等。当然,阅读本书不需要这些东西,但要学习Swift,必须有合适的专业工具。

首先,强烈建议你以交互方式运行本书列出的代码。为此,需要一台运行OS X 10.10(Yosemite)或OS X 10.11(El Capitan)的Macintosh计算机;还需要Xcode 7,它提供了Swift编译器和配套环境。最重要的是,你需要加入苹果开发者计划,这样才能充分利用El Capitan和Xcode 7。如果你还未加入苹果开发者计划,可访问https://developer.apple.com/programs,其中提供了有关如何加入该计划的完整信息。

将Xcode 7下载并安装到Mac计算机后,便可以开始学习Swift了。1.2.2 与Swift交互

首先,我们将通过一个有趣的交互式环境——REPL,来探索Swift。REPL是Read-Eval-PrintLoop(读取-执行-输出-循环)的首字母缩写,这指出了这个工具的特征:它读取指令、执行指令、输出结果,再重新开始。

事实上,这种交互性是Swift有别于C和Objective-C等众多编译型语言的特点之一。如果你使用过Ruby或Python等提供了REPL环境的脚本语言,就知道这并非什么新东西,但对编译型语言来说,这种理念还是很新颖的。只要问问C、C++或Objective-C开发人员就知道,他们很多时候都希望能够直接运行代码,而不用创建包含调试语句的源代码文件,再编译、运行并查看结果。Swift REPL的优点在于,它让上述重复而漫长的工作流程一去不复返了。

这种交互性带来的另一大好处是,它让学习新语言这种原本艰难的任务变得容易多了。你不用再学习一系列复杂的编译工具,也无需了解集成开发环境的细枝末节,只需将全部精力都放在新语言本身上。事实上,本书前半部分将探索、测试、细究Swift的方方面面,你将很快发现,以这种交互方式学习能够更快地理解Swift语言本身。

不需要运行阶段环境就能实时运行代码,一开始这可能让人感觉怪怪的,但很快你就会喜欢它提供的即时结果。事实上,REPL会让有些人想起以前的岁月:在家用计算机革命的早期,BASIC等解释型语言就提供了这种交互性。真是从终点又回到了起点。1.3 准备出发

已下载了Xcode 7?这很好,但请暂时将它抛在脑后吧。事实上,我鼓励你去探索Xcode 7及其新特性,但接下来的几章将把注意力完1全放在Terminal中的REPL上。

在简体中文版Mac操作系统中被称为“终端”,故本书有时也会1用终端来代指它。——编者注

如果你以前没有运行过Terminal应用程序,也不用担心。在Mac计算机中,它位于文件夹Applications/Utilities下。要运行它,最简单的方式是单击图标Spotlight,再输入Terminal,如图1-1所示。

图 1-1 使用Spotlight来查找应用程序Terminal

另一种方法是,单击Dock中的Finder图标,再选择菜单Go>Utilities{2[在简体中文版Mac操作系统中被称为“实用工具”。——编者注,如图1-2所示。

图 1-2 Finder菜单栏中的Go菜单

这将打开一个新的Finder窗口,其中显示了文件夹Utilities的内容,如图1-3所示。要找到应用程序Terminal,可能需要向下滚动。双击Terminal图标启动这个应用程序。

图 1-3 在Finder中查找Terminal

启动Terminal后,将看到类似于图1-4所示的窗口。在你的Terminal窗口中,文本和背景色可能与这里显示的不同。

图 1-4 Terminal窗口

至此,差不多为探索Swift做好了准备,但在此之前,还需要在这个新打开的Terminal窗口中执行几个命令。

首先,输入下面的命令并按回车:sudo xcode-select -s /Applications/Xcode.app/Contents/Developer/

系统将提示你输入管理员密码。按要求输入即可。必须执行这个命令,它是用来确保Xcode 7是Mac计算机运行的Xcode默认版本,以防止你安装的是以前的Xcode版本。好消息是,你只需执行一次这个命令。它指定的设置将被保存,除非你要切换到其他Xcode版本,否则不用再执行这个命令。

输入下面的命令并按回车以进入Swift REPL:xcrun swift

根据你以前使用Xcode的情况,可能出现类似于图1-5所示的对话框,要求你输入密码。如果出现该对话框,输入密码即可。

图 1-5 输入用户名和密码

很快就会出现下面的问候消息:Welcome to Apple Swift version 2.0. Type :help for assistance. 1>

祝贺你走到了这一步。下面开始探索之旅。1.4 开始探索Swift

至此,你运行了Swift REPL,它位于Terminal窗口中,耐心地等待你执行命令。Swift掌握了控制权,它显示一个提示符,告诉你可以输入命令了。每次启动REPL时,提示符都为1和大于号。下面按回车键执行检查:Welcome to Apple Swift version 2.0. Type :help for assistance. 1> 2>

每当你输入一行后,提示符数字都加1——非常简单。当你输入命令时,提示符中不断增大的数字提供了参考点。1.4.1 帮助和退出

Swift内置了REPL命令帮助信息。在提示符下输入:help可列出REPL命令清单,这些命令开头都有一个冒号,Swift使用它来区分REPL命令和Swift语句。

请输入:help(它本身也是一个命令),以查看命令清单。清单中的命令很多,不少都与调试相关,但大部分都不用考虑。

要退出Swift并返回到Terminal的默认shell,可随时执行命令:quit。退出REPL后,要再次进入Swift,只需在shell提示符下执行命令xcrun swift。1.4.2 Hello World

期待已久的时刻到了。每个程序员学习新语言时,都首先会编写必要的代码来向世界问好。稍后你将看到,使用Swift编写这样的代码易如反掌。

来道开胃菜:显示一句俏皮话,作为你首次与这种新语言打交道的问候语。下面用法语向世界问好。在提示符2>下输入下面的代码并按回车:print("Bonjour, monde")

屏幕上的内容如下:Welcome to Apple Swift version 2.0. Type :help for assistance. 1> 2> print("Bonjour, monde")Bonjour, monde 3>

祝贺你编写了第一行Swift代码。必须承认,这有点小儿科,但总算开始了。这个示例还表明编写可执行的代码很容易。

这行代码很简单。print是一个Swift方法,命令计算机显示括号内用引号括起的所有内容(字符串)。方法指的是一组可通过指定名称执行的指令。在本书中,你将用到很多常见的Swift方法,其中print你将经常使用到。

现在是学习一个快捷键的好时机,它让你能够更高效地使用REPL。下面来再次使用方法print,但这次在输出末尾加上一个惊叹号(!)。你可能想再次输入整个命令,但REPL记录了你以前输入的命令,你只需按上箭头键,刚才输入的代码行将显示出来,且光标位于行尾。你只需用左箭头键向左移两个字符,再输入惊叹号。然后,按右箭头键两次,将光标重新移到行尾,再按回车键。 3> print("Bonjour, monde!")Bonjour, monde! 4>

REPL会记录你输入的每行代码,你可不断按上箭头键来遍历以前输入的所有命令。

至此,你掌握了一项基本技能——知道如何让Swift显示一串文本。这微不足道,但为理解Swift开了个好头。咱们接着往下走,看看一些简单而重要的Swift结构。1.5 声明的威力

如果回想一下中学的代数课,你肯定还记得变量是表示某种量的占位符。当你说 x 等于12或 y 等于42时,实际上是在声明,将某个变量声明为特定的数字。

Swift让代数课老师自豪,它也能够声明变量,但使用的语法稍有不同。请输入如下内容: 4> var x = 12x: Int = 12 5>

你刚才使用关键字var声明了第一个变量。第4行让Swift将变量x声明为12,Swift完全按你的指示做,将变量x声明为12。不仅如此,Swift还更进一步:将x声明为值为12的Int变量。

Int是什么呢?它是integer的缩写,表示不带小数部分的整数。通过像前面那样输入12,让Swift对被赋值的变量做出了推断:x是一个值为12的整数变量。在响应中,Swift使用表示法x: Int指出了这个变量的类型。稍后将更详细地介绍这种表示法。

前面不费吹灰之力就声明了一个名为x的变量,下面将问题再弄得复杂一些,声明第2个变量: 5> var y = 42.0y: Double = 42 6>

这里添加了小数点和0,这种表示法告诉Swift,y是一个Double变量。Double表示带小数部分的数字,不用于表示整数,而用于表示实数(也叫浮点数)。Float还是Double?如果你使用过其他编程语言,可能熟悉浮点数,知道它们分两种:Float和Double。Float通常长32位,而Double通常长64位(精度是Float的两倍)。除Double类型外,Swift也支持Float类型。然而,鉴于现代计算机体系结构是64位的,Swift默认使用Double类型来表示浮点数,而在本书的示例中,总是使用Double类型。

下面简单地复习一下。在前面的两种情况下,Swift都给变量指定了类型。变量x和y的类型分别是Int和Double,只要不重新启动REPL,这种差别将始终存在。

声明变量后,就可将不同的值赋给它。例如,前面将数字12赋给了变量x。将不同的值赋给变量很简单,只需使用等号即可: 6> x = 28 7>

注意到将数字28赋给变量x时,Swift没有任何反应。下面核实一下这个新值是否赋给了变量x: 7> print(x)28

与预期的一样,x存储的是最后一次赋给它的值:28。

还可以将一个变量的值赋给另一个变量。为核实这一点,下面将变量y赋给变量x。你猜结果将如何呢? 8> x = yrepl.swift:8:5: error: cannot assign a value of type 'Double' to a value of type 'Int'x = y ^ 8>

Swift显示的错误消息非常详细,提供了错误所在的行号和列号(这里是第8行和第5列),并使用冒号分隔它们。在错误消息后面,还显示了相应代码行的内容,并用脱字符指出了错误的位置。最后,由于存在错误,在接下来显示的提示符中没有将数字增加到9,而再次使用以前的数字8。(这相当于Swift在对你说:“哥们,别紧张,再试试。”)变量名包含什么?在Swift中,变量名可以用除数字外的任何字符打头。前面使用的是单字母变量名,但应使用更长、意义更丰富的变量名,以提高代码的可读性。

这里到底出了什么问题呢?很简单,你试图将类型为Double的变量y赋给类型为Int的变量x,这种赋值违反了Swift的类型规则。稍后将更详细地介绍类型,现在来看看能否规避这种规则。

假设你一根筋,就是要将y的值赋给x,即便它们的类型不同。你完全可以达到目的,但需要做些“说服”工作。前面说过,x的类型为Int,而y的类型为Double;考虑到这一点后,可输入如下语句: 8> x = Int(y) 9> print(x)42 10>

经过一番“说服”后,赋值成功了。个中原因是什么呢?

第8行将变量y的Double值“转换”成了变量x的类型。只要进行显式转换,Swift就允许这样赋值。稍后将更详细地讨论类型转换。

保险起见,使用命令print显示了变量x的值。与预期的一样,现在变量x的值为整数42。1.6 常量

在很多情况下,变量都很有用,因为它们的值可随时间而变。在循环中,变量非常适合用于存储临时数字、字符串以及本书后面将讨论的其他对象。

在Swift中,另一种可用于存储值的结构是常量。顾名思义,常量存储的值始终不变。不同于变量,常量一旦赋值就不能修改,就像被锁定一样。然而,与变量一样,常量也有类型,且类型一旦指定就不能改变。

下面来看看如何使用常量:声明常量z,并将变量x的值赋给它: 10> let z = xz: Int = 42 11>

第10行使用了let命令,这是用于创建常量的Swift关键字。常量z的类型和值都与变量x相同:它是一个值为42的Int常量。

如果常量的值真是固定不变的,就不能将另一个数字或变量赋给它。下面来检验这一点: 11> z = 4repl.swift:11:3: error: cannot assign to value: 'z' is a 'let' constantz = 4~ ^repl.swift:10:1: note: change 'let' to 'var' to make it mutablelet z = x^~~var 11>

试图给常量z重新赋值引发了错误。同样,Swift精准的错误报告指明了方向,它指出了错误所处的行号(11)和列号(3)。在这里,Swift还更进了一步,建议将第10行的关键字let改为var,这样就可以赋值了。对于Swift的这种聪明劲,你怎么看?

为何Swift要同时支持变量和常量呢?考虑到变量可以修改,而常量不能,使用变量不是更灵活吗?问得好,答案要在底层编译器技术中去找。知道内存单元存储的值不会变时,Swift编译器可更好地决策和优化代码。对于不变的值,务必在代码中使用常量来存储;仅当确定值将发生变化时,才使用变量来存储。总之,常量需要的开销比变量小,这正是因为它们不变。

在你学习Swift开发的过程中,将在确定值不变的情况下越来越多地使用常量。事实上,苹果鼓励在代码中使用常量,不管这样做出于什么考虑。1.7 类型

在本章前面,Swift自动推断出了变量的类型,你注意到了吗?你不用输入额外的代码去告知Swift变量的类型究竟为Int还是Double,Swift自会根据等号右边的值推断出变量或常量的类型。

计算机语言使用类型将值和存储它们的容器分类。类型明确地指出了值、变量或常量的特征,让代码的意图更清晰,消除了二义性。类型犹如不可更改的契约,将变量或常量与其值紧密关联在一起。Swift是一种类型意识极强的语言,这一点在本章前面的一些示例中已经体现出来了。

表1-1列出了Swift基本类型。还有其他一些类型没有列出。另外你将在本书后面看到,可创建自定义类型,但目前我们只使用这些类型。

表1-1 变量类型类型特征示例只有两个可能取值的类Booltrue、false型,要么为true要么为falseInt、32或64位的整数值,用于3、Int32、表示较大的数字,不包含小数117、-502001、Int64部分10045Int88或16位的整数,用于表示-11、83、122较小的数字,不包含小数部分、Int16UInt32或64位的正整数,用于3、117、50、表示较大的数字,不包含小数、UInt32、10045UInt64部分UInt8或16位的正整数,用于表8、示较小的数字,不包含小数部44、86、255UInt16分324.可正可负的浮点数,可能Float147、-2098.8388、包含小数部分、Double16.0Char用双引号括起的单个字“A”“!”“*”“5”acter符、数字或其他符号“Jambalaya”Strin用双引号括起的一系列字“Crawfish Pie”“Filet g符Gumbo”

前面介绍过Int,但未介绍Int8、Int32和Int64,UInt、UInt8、UInt32和UInt64也未介绍。可正可负的整数被称为有符号整数,其表示类型包括8、16、32和64位;只能为正的整数被称为无符号整数,也有8、16、32和64位版本。如果没有指定32或64位,Int和UInt默认为64位。事实上,在开发工作中很少需要考虑类型的长度。就现在而言,请不要考虑这些细节。1.7.1 检查上限和下限

表1-1列出的每种数值类型都有上限和下限,即每种类型可存储的数字都不能小于下限,也不能大于上限,这是因为用于表示数值类型的位数是有限的。Swift让你能够查看每种类型可存储的最大值和最小值: 11> print(Int.min)-9223372036854775808 12> print(Int.max)9223372036854775807 13> print(UInt.min)0 14> print(UInt.max)18446744073709551615 15>

在类型名后面加上.min或.max,即可获悉相应类型可存储的上下限值。第11~14行显示了类型Int和UInt的取值范围。你也可以自己检查表1-1列出的其他类型的可能取值范围。1.7.2 类型转换

鉴于类型是值、常量和变量的固有特征,你可能想知道不同类型交互式需要遵循的规则。还记得吗,在本书前面的一个示例中,你尝试将一种类型的变量赋给另一种类型的变量。第一次尝试这样做时引发了错误;经过“说服”后,才让Swift同意将一个Double型变量赋给一个Int型变量。下面来重温这个示例(不用重新输入代码,只需在Terminal中向上滚动到能够看到前面输入的代码即可): 4> var x = 12x: Int = 12 5> var y = 42.0y: Double = 42

这些代码分别将Int和Double值赋给变量x和y,然后试图将y的值赋给x: 8> x = yrep.swift:8:5: error: cannot assign a value of type 'Double' to a value of type 'Int'x = y ^ 8> x = Int(y) 9> print(x)42

第4行声明了变量x并将数字12赋给它,这使其类型为Int。接下来,将y声明为Double变量。然后,将y赋给x时引发了错误,这迫使我们将y的值转换为Int,如第8行所示。这个过程称为强制转换(casting),即强制将值从一种类型转换为另一种类型。在计算机语言中,这种功能被称为类型转换。每种语言都有其类型转换规则,Swift当然也不例外。

一种常见规则是,类型转换只能在相似的类型之间进行。在C等流行的计算机语言中,可在整数和双精度浮点数之间转换,因为它们都是数值类型。但强行将整数转换为字符串属于非法类型转换,因为它们是截然不同的类型。在这方面,Swift更灵活些。请尝试下面的操作: 15> var t = 123t: Int = 123 16> var s = String(t)s: String = "123" 17>

这里声明了变量t,并将一个Int值赋给它。接下来,声明了另一个变量s,将Int变量t的值强制转换为String类型,并将结果赋给变量s。

能将String类型强行转换为Int乃至Double吗? 17> var u = Int(s)u: Int? = 123 18> var v = Double(s)v: Double? = 123

可以。Swift让你能够将数据从一种类型转换为另一种类型。咱们来搅搅局,使用不是数字的字符串给Swift设置点障碍: 19> var w = Int("this is not a number")w: Int? = nil 20>

显然,将这个字符串转换为整数是不明智的,因此Swift不允许这样做。但Swift没有返回错误,而返回表示什么都没有的nil。你可能感到迷惑,响应第17~19行时Swift显示了Int?,这其中的问号到底是什么意思呢?这表明myConvertedInt是特殊的Int类型:可选Int类型。可选类型将在后面更详细地介绍,你现在只需知道它们让变量可以为特殊值nil。1.7.3 显式地声明类型

让Swift推断变量或常量的类型很方便:不用告诉Swift变量的类型是整型还是浮点型,它根据赋给变量的值就能推断出来。然后,有时需要显式地声明变量或常量的类型,Swift允许你在声明中指出这一点: 20> var myNewNumber : Double = 3myNewNumber: Double = 3 21>

将变量或常量声明为特定类型很简单,只需在变量或常量的名称后面加上冒号和类型名。上面的代码将myNewNumber声明为Double变量,并将数字3赋给它,而Swift忠实地报告了声明结果。

如果在第20行省略Double,结果将如何呢?Swift将根据赋给变量myNewNumber的值确定其类型为Int。在这个示例中,我们推翻了Swift的假设,强制将变量声明为所需的类型。

如果没有给变量或常量赋值,结果将如何呢? 21> var m : Intrepl:swift:21:1 error: variables currently must have an initial value when entered at the top level of the REPLvar m : Int^ 21> let rr : Intrepl:swift:21:1: error: variables currently must have an initial value when entered at the top level of the REPLlet rr : Int^

第21行将变量m声明为Int类型,但没有在声明的同时给它赋值。Swift显示一条错误消息,指出在REPL中必须给变量赋初值。

接下来的一行使用let命令将rr声明为Int常量,但没有赋值。注意到Swift显示了同样的错误消息。在REPL中,无论是变量还是常量,都必须在声明时给它们赋值。1.8 字符串

前面简要地介绍了数值类型,但还有一种Swift类型也用得非常多,它就是String类型。前面说过,在Swift中,字符串是用双引号("")括起的一系列字符。

下面是合法的字符串声明: 21> let myState = "Louisiana"myState: String = "Louisiana" 22>

下面的字符串声明亦如此: 22> let myParish : String = "St. Landry"myParish: String = "St. Landry" 23>

这些示例分别演示了类型推断和显式声明类型。在第一个示例中,Swift根据赋给变量的值确定其类型;在第二个示例中,显式地指定了变量的类型。这两种做法都可行。1.8.1 字符串拼接

可使用加号(+)运算符将多个字符串连接,或者说拼接起来,组成更大的字符串。下面声明了多个常量,再将它们拼接起来,生成一个更长的常量字符串: 23> let noun = "Wayne"noun: String = "Wayne" 24> let verb = "drives"verb: String = "drives" 25> let preposition = "to Cal's gym"preposition: String = "to Cal's gym" 26> let sentence = noun + " " + verb + " " + preposition + "."sentence: String = "Wayne drives to Cal's gym." 27>

第26行将6个字符串拼接在一起,再将结果赋给常量sentence。1.8.2 Character类型

前面介绍了三种类型:Int(用于存储整数)、Double(用于存储带小数的数字)和String(用于存储一系列字符)。在Swift中,你必将用到的另一种类型是Character,它实际上是特殊的String。类型为Character的变量和常量包含单个用双引号括起的字符。

下面就来试一试: 27> let myFavoriteLetter = "A"myFavoriteLetter: String = "A" 28>

你可能抓破了头皮也想不明白,Swift为何说变量myFavoriteLetter的类型为String?如果没有显式地指定类型Character,Swift默认将用双引号括起的单个字符视为String类型。Character是Swift无法推断的类型之一,下面来纠正上述错误: 28> let myFavoriteLetter : Character = "A"myFavoriteLetter: Character = "A" 29>

现在结果与期望一致了!

既然字符串是由一个或多个字符组成的,那么应该能够使用字符来创建字符串。确实如此,为此可使用前面用于拼接字符串的加号(+)运算符,但需要注意的是,必须先将字符强制转换为String类型: 29> let myFavoriteLetters = String(myFavoriteLetter) + String(myFavoriteLetter)myFavoriteLetters: String = "AA" 30>

如果你以前使用过对字符串拼接支持不强的C或Objective-C语言,将感觉到Swift字符串拼接非常简单。要拼接字符,在C语言中必须使用函数strcat(),而在Objective-C中必须使用Foundation类NSString的方法stringWithFormat:,而在Swift中只需使用加号运算符就能拼接字符和字符串,因此需要输入的代码少得多。这充分说明了Swift的简洁和优美:拼接字符串就像将两个数字相加一样。说到将数字相加,下面来看看在Swift中如何执行简单的数学运算。1.9 数学运算符

Swift很擅长做数学运算。前面介绍过String类型可使用加号来拼接字符串,但加号并非只能用于拼接字符串,它还是加法运算的通用表示方式,而现在正是探索Swift数学运算功能的好时机。来看一些执行算术运算的数学表达式: 30> let addition = 2 + 2addition: Int = 4 31> let subtraction = 4 - 3subtraction: Int = 1 32> let multiplication = 10 * 5multiplication: Int = 50 33> let division = 24 / 6division: Int = 4 34>

这里演示了四种基本运算:加(+)、减(-)、乘(*)、除(/)。Swift提供的结果符合预期,它给常量指定的类型(Int)也符合预期。同样,Swift根据等号右边的值推断出这些常量的类型为Int。

还可使用%运算符来执行求模运算,它返回除法运算的余数: 34> let modulo = 23 % 4modulo: Int = 3 35>

在Swift中,甚至可将求模运算符用于Double值: 35> let modulo = 23.5 % 4.3modulo: Double = 2.0000000000000009 36>

另外,加号和减号还可用作单目运算符。在值前面加上加号意味着正数,加上减号意味着负数: 36> var positiveNumber : Int = +33positiveNumber: Int = 33 37> var negativeNumber : Int = -33negativeNumber: Int = -33 38>1.9.1 表达式

Swift全面支持数学表达式,包括标准的运算符优先级(按从左到右的顺序先执行乘法和除法运算,再执行加法和减法运算): 38> let r = 3 + 5 * 9r: Int = 48 39> let g = (3 + 5) * 9g: Int = 72 40>

第38行先将5乘以9,再将结果加上3,而第39行将前两个值用括号括起来,因此先将这两个值相加,再将结果与9相乘。Swift与其他现代语言一样按规范顺序执行数学运算。1.9.2 混用不同的数值类型

如何混用小数和整数,结果如何呢? 40> let anotherDivision = 48 / 5.0anotherDivision: Double = 9.5999999999999996 41>

这里将整数48除以小数5.0。小数点提供了足够的线索,让Swift将相应数字的类型视为Double。结果常量anotherDivision的类型也被指定为Double。这里演示了Swift的类型提升概念:将Int值48与一个Double值放在同一个表达式中时,它被提升为Double类型。同样,常量也被指定为Double类型。这种规则必须牢记。

在同一个表达式中包含不同类型的数值时,总是将表达力较弱的类型提升为表达力较强的类型。由于Double类型可表示Int值,而Int类型无法表示Double值,因此将Int值提升为Double值。1.9.3 数值表示

在Swift中,可以多种方式表示数值。本章前面使用的都是最常见、最自然的表示方式:十进制,即以10为底的计数法。下面来看看其他表示数值的方式。

1. 二进制、八进制和十六进制

如果你有编程经验,肯定遇到过以2、16甚至8为底的数字,它们分别被称为二进制、十六进制和八进制。这些进位制在软件开发中经常会出现,根据它们本身的特性使用简捷记法很有帮助: 41> let binaryNumber = 0b110011binaryNumber: Int = 51 42> let octalNumber = 0o12octalNumber: Int = 10 43> let hexadecimalNumber = 0x32hexadecimalNumber: Int = 50 44>

二进制数用前缀0b表示,八进制数字用0o表示,而十六进制数用0x表示。当然,没有前缀意味着为十进制数。

2. 科学记数法

另一种表示数字的方法是科学记数法,这种记数法可简化大型小数的表示: 44> let scientificNotation = 4.434e-10scientificNotation: Double = 0.00000000044339999999999999 45>-10

其中e表示以10为底的指数,这里为4.434×10。

3. 大数字表示法

如果你曾坐在Mac计算机前数数字末尾有多少个0,以确定其量级,肯定会喜欢下面这种特性。Swift支持下面这种方式表示大数,让其量级一目了然: 45> let fiveMillion = 5_000_000fiveMillion: Int = 5000000 46>

下划线会被Swift忽略,但这些下划线对提高数字的可读性大有裨益。1.10 布尔类型

Swift支持的另一种类型是Bool,即布尔类型。布尔类型的取值要么为true要么为false,通常在比较表达式中使用它们来回答类似于下面的问题:12是否大于3,或55是否等于12?在软件开发中,从结束对象列表迭代到确定一组条件语句的执行路径,经常会用到这样的逻辑比较: 46> 100 > 50$R0: Bool = true 47> 1.1 >= 0.3$R1: Bool = true 48> 66.22 < 7$R2: Bool = false 49> 44 <= 1$R3: Bool = false 50> 5.4 == 9.3$R4: Bool = false 51> 6 != 7$R5: Bool = true 52>

这里使用了如下比较:大于、大于等于、小于、小于等于、等于、不等于。根据比较结果,返回布尔值true或false。这里比较了Int字面量和Double字面量,旨在说明这两种数值类型都是可以比较的,甚至可以对Double值和Int值进行比较。结果

注意到这里没有使用关键字let或var将布尔表达式的结果赋给常量或变量;另外,这些条件表达式的结果各不相同,如第49行的结果所示:$R3: Bool = false

其中的$R3是什么呢?在Swift REPL中,这被称为临时变量,它存储了结果的值,这里为false。可像声明过的变量一样引用临时变量: 52> print($R3)false 53>

还可以给这些临时变量赋值,就像它们是声明过的变量一样。如何比较字符串?如果能够使用前述比较运算符来检查字符串是否相等,那就太好了。如果你使用过C或Objective-C,就知道检查两个字符串是否相等很麻烦。在C语言中,需要像下面这样做:int result = strcmp("this string", "that string")在Objective-C中,需要像下面这样做:NSComparisonResult result = [@"this string" compare:@ "that string"];在Swift中,编写比较字符串的代码易如反掌,这些代码也很容易理解: 53> "this string" == "that string"$R6: Bool = false 54> "b" > "a"$R7: Bool = true 55> "this string" == "this string"$R8: Bool = true 56> "that string" <= "a string"$R9: Bool = false 57>结果说明了一切:Swift比较字符串的方式更自然、更具表达力。1.11 轻松显示

前面在REPL中显示字符串时,使用的都是方法print。下面重温这个方法,看看如何使用它来显示更复杂的字符串。

方法print提供的便利之一是,不费吹灰之力就能将变量的值嵌入到其他文本中。如果你熟悉C或Objective-C,就知道设置文本输出格式需要输入的代码非常多,最典型的例子是C语言中的方法printf和Objective-C中的方法NSLog()。请看下面的Objective-C代码片段:NSString *myFavoriteCity = @"New Orleans";NSString *myFavoriteFood = @"Seafood Gumbo";NSString *myFavoriteRestaurant = @"Mulates";NSInteger yearsSinceVisit = @3;NSLog(@"When I visited %@ %d years ago, I went to %@ and ordered %@.", myFavoriteCity, yearsSinceVisit, myFavoriteRestaurant, myFavoriteFood);

如果你能看懂这段代码,就知道它很糟糕,其中的原因有多个。首先,变量的位置与其值将显示的位置不同,这要求你以正确的顺序指定变量,否则结果将不符合预期。其次,设置两种类型不同的变量的格式时,需要使用不同格式设置代码:对于NSString变量,需要使用%@;对于NSInteger变量,需要使用%d(如果你不熟悉格式设置代码,也不用担心,因为Swift不使用它们)。

在Swift中,无需使用格式设置代码,也无需考虑格式设置代码和变量的顺序。相反,只需将变量放在要显示的位置,它们就会与其他文本一起显示出来。下面是上述Objective-C代码的Swift版本: 57> let myFavoriteCity = "New Orleans"myFavoriteCity: String = "New Orleans" 58> let myFavoriteFood = "Seafood Gumbo"myFavoriteFood: String = "Seafood Gumbo" 59> let myFavoriteRestaurant = "Mulates"myFavoriteRestaurant: String = "Mulates" 60> let yearsSinceVisit = 3yearsSinceVisit: Int = 3 61> print("When I visited \(myFavoriteCity) \(yearsSinceVisit) years ago, I went to \(myFavoriteRestaurant) and ordered \(myFavoriteFood).")When I visited New Orleans 3 years ago, I went to Mulates and ordered Seafood Gumbo. 62>

第61行中用于显示变量的标记非常简单,其中使用了嵌入表示法\()来引用第57~60行声明的四个常量。这种表示法非常简洁,如果将其与前述语言的处理方式进行比较,这一点尤其明显。

同样,将合并得到的字符串赋给变量与显示它一样简单: 62> let sentence = "When I visited \(myFavoriteCity) \ (yearsSinceVisit) years ago, I went to \(myFavoriteRestaurant) and ordered \ (myFavoriteFood)."sentence: String = "When I visited New Orleans 3 years ago, I went to Mulates and ordered Seafood Gumbo." 63>

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载