本文章纯粹是中文版《The Swift Programming Language》的学习笔记,所以绝大部分的内容都是文中有的。本文是本人的学习笔记,不是正式系统的记录。仅供参考
以下还是有很多没看懂、不确定的地方,我会以“存疑”的注解指出。
在此感谢中文版翻译者,这极大地加快了 Swift 的学习速度。
@H_502_6@Reference:
原版:The Swift Programming Language
中文版:Swift 3 编程语言
几个无法分类的知识:
1 - Swift 不需要 main()
函数,全局的第一段代码就是程序的入口。(存疑)
2 - Swift 中没有像 C 里面一样,非常明确地区别“声明”和“定义”的概念,全部的定义都是 “声明 + 定义”。
变量和常量
声明变量和常量
let aConstant = 42 let aConstantDouble : Double = 70 // 个人推荐
这样根据后面的值假定常量的类型。第一个例子里面,常量的类型就被设置成了Int
。而第二个例子里面,虽然初始化值给的是一个Int,但是前面显式地说明了这是一个Double
类型变量,所以这就是一个 Double 类型。
变量使用的是var
。
数组
在 Swift 里面,数组和关联数组成为了基本数据类型(在 Objective-C 里面是类),这大大简化了数据操作。
声明方式如下:
var shoppingList = ["catfish","water","popcorn"] var shoppingList = [String]()
其中第一行是定义+初始值。第二行则不赋予初始值
关联数组(Dictionary)
var aDict = [:] var aDict = [String:Float]() // 推荐 var aListOfSalaries = [ "Andrew": 10000.0,"Bob": 15000.0 ]
上面第二种方法是详细的定义,具体限制了关联数组的 key 和 value 的类型。
控制流
基本上和 C 差不多,但不需要括号。不过有{}
。
条件操作有:if
、switch
循环操作有:for-in
,for
,while
,repeat-while
(不是 “do-while”)。
注意
:if
的条件不循序用一个普通变量的值作为判断条件体了,只能布尔判断值。比如 “if some_value
” 就是不合法的写法。
Optional 变量
如果声明变量的时候加入?
,那么变量就是可选的(optional)
此时,变量可以置为 nil
值。
猜测这个方法就是相当于 C 里面的指针或者是其他方法中的引用(不确定)。
Arrar 和 Dictionary 中的 for-in
for number in someArray { ... } for (kind,number) in someDictionary { ... }
上面是使用 “for-in
” 语法来 access array 和 dict 的方法。当然,array 和 dict 也可以嵌套。
循环
while n < 200 { ... } repeat { ... } while m < 100 for i in 0..<4 { } // 表示 [0,4) for i in 0...4 { } // 表示 [0,4]
函数和簇(闭包)
使用 func
来声明和定义函数:
func greeting (persion: String,day: String) -> String { ... }
可以使用 “元组
”(tuple
)来创建仅在该函数中使用的复合值(类似 struct
):
func calculate (scores:[Int]) -> (min: Int,max: Int,sum: Int) { ... }
此外,可以把函数作为值返回:
func theFunc(number: Int) -> Int { ... } func retuanAFunc() -> (Int -> Int) { return theFunc }
func someFunc() -> Int { var error: Int = 0 ... func checkError() { if (...) { error = -1 } } ... return error }
对象和类
使用关键字 class
加花括号来构建一个类。与前面其他格式中花括号的作用一眼,都只是用来作为作用域。
var anInstance = aClass // 很像 C++
使用点语法来访问类中的成员与方法。
初始化函数:init
,接近 Objective-C 中的 init
反初始化函数:deinit
,接近 Objective-C 中的 dealloc
成员函数重载:在 func 前面加上 override
关键字。
getter / setter
声明成员时,额外可以声明 getter / setter:
class SomeClass : FatherClass { var radius : Int init (radius : Int) { super.init (radius) self.radius = radius } var circle : Double { get { ... } set { ... // setter的参数如果未定义的话,默认叫做 `newValue`。也可以显式地定义。 } } }
willset 和 didSet
有时候,如果不需要自行实现 set / get操作,但需要在值更新前后操作的话,可以针对该值定义 willSet
和 didSet
函数:
var squre : Double { willSet: { ... } }
枚举和结构体
这其实是我最搞不懂的元素之一了,目测我以后只会用最基础的部分。
使用 enum
创建枚举。enum 可以包括函数
:
enum PokerFace { case ace = 1 // 注意这里如果不赋初始值的话,默认是 1 case two,three,four,five,six,seven,eight,nine,ten case jack,queen,king func decription() -> String { switch self { case .ace: return "ace" case .jack: return "jack" case .queen: return "queen" case .king: return "king" default: return String (self.rawValue) // Note } } }
注意隐含的 rawValue
值。
可以用构造函数创建一个 enum 的实例:
let aRank = Rank (rawValue : 3) let aRank = Rank (.three)
使用 struct
定义结构体:
struct Card_st { var rank : Rank var suit : Suit func simpleDescription () -> String { return ... } }
struct 的行为与 class 很类似,但传递时,struct 传递的是拷贝,而 class 传递的是引用
struct 也有 initializer
协议和扩展
协议
protocol ExampleProtocol { var simpleDescription: String {get} mutating func adjust () }
声明部分的两行分别代表一下意思:
class、struct 和 enum 都可以有协议。
声明一个类,表示符合某个协议,在冒号后面加就好了:
class SomeClass : ExampleProtocol { ... }
扩展
extansion Int: ExampleExtansion { ... }
上面表示为 Int 类型添加一个名为 “ExampleExtension” 的扩展。
此时你可以创建一个叫做 “ExampleProtocol” 的 Int 变量,这个时候, “ExampleExtension” 的语义就变成了 “添加了 ExampleExtension 扩展的 Int 类型”。这是的基本类型也好像类一样继承了。
错误处理
使用遵循 Error 协议
的类型来表示错误,比如:
enum ExampleError : Error { case outOfPaper case noToner case onFire }
使用 throw
来抛出错误。使用 throws
标记可以抛出错误的函数:
func send (job : Int,toPrinter printerName : String) throws -> String { ... if printerName == ... { throw ExampleError.noToner } return "..." }
do { ... } catch { print(error) // 这个貌似是隐含的数据类型?不确定 }
do { ... } catch PrinterError.onFire { ... } catch let printerError as PrinterError { print ("Printer error: \(printerError).") } catch { print(error) }