1. 在开发iOS应用之前需要学习一些Swift语言基础,在Swift Playground上练习Swift语法是一个快捷、有效同时十分有趣的过程。与iOS应用开发相比,Swift Playground是一个独立的工程项目,使用扩展名为playground的项目文件,它是苹果公司首次与Swift语言一起推出的项目。我们知道Swift是一种脚本风格的语言,而Swift Playground正是针对这个特性推出的运行平台(类似可运行脚本的控制台),可以与代码交互直接看到执行结果。Playground在英语中意为操场-学生、青少年嬉戏玩耍的地方,Swift Playground的logo是一个两个儿童玩耍跷跷板的图案,如下图。
2. 本文的学习目标
1) 区分常量和变量
2) 知道何时使用隐式和显式的类型声明
3) 理解使用可选类型(optionals)和可选类型绑定(optional binging)的好处
4) 区分可选类型(optionals)和隐式解包可选类型(unwrapped optionals)
5) 理解条件语句和循环的目的
6) 使用switch语句用于超出二进制条件的条件分支
7) 使用where子句在条件语句中加入附加约束
8) 区分函数、方法和构造器(initializers)
9) 区分类、结构体和枚举
10) 理解继承(inheritance)和协议(protocol)所遵循的语法
11) 输入和使用UIKit
3 基本类型
3.1 常量在第一次声明后就始终数值不变,而变量则是可以声明后仍可改变数值。一个常量被指为非改变的(immutable),一个变量则被指为可改变的(mutable)。使用let声明一个常量,使用var声明一个变量。
上面用到了类型判断(type inference),根据myVariable后面的初始值判断myVariable是Int类型,同样myConstant也是Int类型。完整的语句如下:
如果初始值和实际类型不一致,则需要显式声明类型,explicitDouble的初始值是Int,因此需要显式声明Double类型。
数据的类型永远不会隐式转换成其他类型,需要进行显式转换处理。下面是一个Int转换成String的例子。
另一种更简单的方法在字符串中添加数值类型,使用“\”和”()”,如下:
3.2 可选类型(optionals)
使用”?”可选类型声明数值可能为空(nil)
可选类型的数值需要使用解包(unwrap)后,才能进行赋值,一个简单直接的方法:使用强制解包”!”进行赋值,只有使用解包操作符才能保证赋的值不是nil。
3.3 数组
数组是一种有序集合的数据类型,使用”[ ]”创建,数组的第一个元素下标为0。
创建一个空数组:
3.4 隐式解包可选类型
隐式解包可选类型是一个可选类型可以当作一个非可选类型数据,不需要每次使用时对其进行解包,在声明类型后面使用”!”而不是”?”。
控制流
Swift有两类控制流语句:1)条件语句,如if和switch;2)循环语句,如for-in和while。
4.1 if语句
4.1.1 if语句嵌套在for-in语句内
4.1.2 在if语句中使用可选类型绑定检查可选类型是否有值
如果可选类型的值是nil,条件判断为false,将跳过if后面{}中的代码。否则,可选类型的值被解包然后赋值给let后面的常量name。
4.1.3 单个if语句可以绑定多个数据
添加where子句到条件判断的语句中,下面如果所有数据绑定成功同时所有条件得到满足,if语句会得到执行。
4.2 Switch语句
Swift的Switch语句十分强大,支持所有类型的数据和大范围比较操作,不仅仅限于整数和等于比较。下面switch语句在vegetable字符串上,比较各种状况和执行其匹配操作。
上面switch允许多个由”,”分隔的匹配状况,与if语句不同,这些分隔状况只要有一个得到满足就会执行匹配操作。switch语句的case子句中一旦执行了匹配操作,其执行完成后就会退出switch语句,因此case子句不需要调用break语句。
switch语句必须保证至少有一个case子句得到执行,因此有时需要提供default子句,当所有case子句没有匹配执行后,default子句会得到执行操作。
4.3 for-in循环
使用范围(Range)操作符
半开范围操作符(..<)不执行最高上标数值,上面代码中i=4不会执行,而闭合范围操作符(…)会执行最高上标数值,下面循环会从0到4执行5次,下划线”_”表示泛匹配(wildcard)。
函数和方法
5.1 函数
函数是一种可重用的、命名的代码片段,可用于程序中多个地方被调用。使用func声明一个函数,函数声明包含零个及以上的参数,以name: Type的形式书写。函数可以有一个返回类型,在尾部以->形式书写,函数的实现部分在”{ }”里面。
调用这个函数时,不用书写第一个参数名称,后面的参数需要书写参数名称。
5.2 方法
在特定类型中定义的函数称为方法(methods),方法显式的关联于其所在定义的类型,只能在该类型或者类型的子类中被调用。下面例子中,调用了String的方法hasSuffix。
调用方法使用点(“.”)语法,下面调用数组的insert方法。
类(Classes)和构造器(Initializers)
6.1 类
在面向对象编程中,程序的行为大多数是基于对象之间的交互,每个对象是一个类的一个实例。类通过属性(properties)保存附加的信息,使用方法定义类本身的行为。使用class声明定义一个类。属性声明和常量、变量的声明一样,写在类的声明定义中;同样方法也和函数的声明一样写在类的声明定义中。下面例子声明一个Share类,拥有一个numberOfSides属性和simpleDescription()方法。
下面例子创建Shape类的一个实例-shape对象,对其属性赋值,调用方法simpleDescription()。
6.2 构造器
构造器是一个准备用来生成一个类实例的方法,其中有对美国属性设置初始值和完成相关设置。使用init声明构造器,下面例子定义一个新类NameShape。
不能直接使用init去调用构造器,而是使用类名和其全部构造器的参数。
6.3 父类和子类
子类继承父类的行为,子类中指向父类使用super,声明一个子类和父类使用”:”。子类的方法使用override重写父类中同名的方法,如果没有用override声明的方法与父类的方法使用相同的名称和参数,会报告编译器错误;同样使用override声明的方法在父类中没有对应的方法,也会报告编译器错误。下面例子定义Square类,父类是NamedShape。
6.4 失败构造器(failable initializers)
有时对象的构造过程需要失败处理,例如传入的参数超出了指定的范围,或者缺少需要的数据,这时不能成功初始化对象就要调用失败构造器,失败构造器能返回nil,使用init?声明一个失败构造器。
6.5 声明多个构造器
在类中,可以有多个关键字关联声明的构造器。特定(designated)构造器不需要任何关键字声明,它是类的主构造器(primary initializer),类的其他构造器必须最终调用主构造器。使用convenience关键字声明的构造器,视为常规构造器,作为二级构造器用于增加类的附加行为或定制化工作,最终需要调用主构造器。类中使用required关键字声明的构造器,表明该类和所有子类都要实现这个构造器,并且在子类的这个构造器前也需要使用required关键字声明。
6.6 类型转化(type casting)
类型转化是一种检查实例类型的方式,判断一个实例是否是一个父类或者子类的实例对象。类型转化有两个操作符:可选类型转化操作符(as?)和强制类型转化操作符(as!),可选类型转化操作符返回一个可选类型数据,这个数据可以是空(nil)表明转化失败,强制类型转化操作符使用在转化结果总是成功,如果失败则触发运行时错误。下面例子显示使用可选类型转化操作符(as?)检查数组中的每个shape是square或者triangle。
枚举和结构体
在Swift语言中,类不是定义数据类型的唯一方式,枚举和结构体具有和类相似的能力。
7.1 枚举
枚举可以定义一组普通类型的、相关联的数据,枚举的使用是一种类型安全(type-safe),枚举可以有自己的方法。使用enum创建一个枚举数据。
上面例子中,枚举的raw-value类型是Int,定义第一个rawvalue的数值,后面的rawvalue会自动递增加1。枚举的raw-value类型也可以使用字符串或者浮点数。
7.2 结构体
结构体支持类的大多数行为,包括方法和构造器。结构体和类的一个最重要的不同在于:结构体总是传数值方式被使用,而类是传引用方式。结构体适用于定义轻量的数据类型,不需要像继承和类型转化这些能力。使用struct创建一个结构体。
协议
协议定义了一些方法、属性和其他实现指定任务和功能的蓝图,并不实际提供任何实际的实现。类、结构体和枚举可以遵循协议,提供实际实现。使用protocol声明一个协议。
上面例子中,{ get }在simpleDescription属性后面,表明该属性是只读的。
类、结构体和枚举使用“类名: 协议名”的形式遵循一个协议,当需要遵循多个协议同时声明一个父类时,父类需要在第一个位置,如“子类名: 父类, 协议1, 协议2, …, 协议n”。下面例子,SimpleClass遵循ExampleProtocol协议,提供实现simpleDescription属性和adjust方法。
协议是第一级类型,可以与其他命名的类型相似,可以创建协议实例。下面例子,创建ExampleProtocol数组,并对数组中的实例依此调用adjust方法。
Swift语言和Cocoa Touch
Cocoa Touch是苹果开发iOS应用的框架集合,Swift语言提供与Cocoa Touch无缝的互操作能力。
iOS应用开发最常见的框架就是UIKit,在Swift语言使用UIKit框架的方法
下面是创建一个红色的正方形视图。
10. Swift Playground界面