
注:本系列,仅为自己读书摘要。如果你想购买此书,请移步到 http://item.jd.com/11732275.html
下面是 《第二章 深入学习Swift语法》的摘抄内容
0.在代码中,变量值可能为空,而错误的使用控制会导致出现错误。为了解决这个问题 Swift 提供了可空类型。可空类型能够安全地检查某个值是否为空,当值不为空时,才会被访问。
1.在运行时,可空类型有两种不同的表示方式:Some
或者 None
。当值不为空时,可空类型用 Optional.Some(value)
表示,否则用 Opational.None
表示,当变量需要存放这两种不同的情况时,我们必须将变量声明为可空类型,在类型说明后面添加一个”?”修饰符(例如,原本的 Int
将变成 Int?
)。不限于类,任意类型都可以徐世伟可空类型。
2.可空类型对值进行了装箱处理,因此不能像对待非可空类型一样对待它们。例如,你不能将一个 String?
当成 String
来用:
1 2 3
| let dic = ["name" : "jim"] let gender = dic["gender"] let say = "Your gender is" + gender
|
3.在运行时,如果你对一个不存在的值进行拆箱,应用程序将崩溃。
4.对于可空类型,在拆箱操作之前,必须检查可空类型是否包含有效值(不为空),类似的代码非常繁琐,为了使代码更加简洁和可读,Swift 使用了一种将检查和拆箱操作合并到一个步骤的语法,即所谓的可空绑定。它为数据的处理提供了一种简短安全的方法,如下代码:
1 2 3 4
| if someOptional != nil{ let someValue = someOptional! }
|
可以被可空绑定替换为:
1 2 3
| if let someValue = someOptional{ }
|
5.泛型结构如下:
1 2 3 4 5 6 7
| func maxValue<T: comparable>(lhs: T, rhs: T) -> T { if lhs > rhs{ return lhs } return rhs }
|
上面的代码中,声明了一个新的函数,并将其命名为 maxValue
,与一般的函数不同,在参数列表前面我们使用了一个 <T: Comparable>
,这表明我们正在定义一个泛型函数。<T: Comparable>
说明这个函数要使用一个泛型 T
,同时 T
必须实现 Comparable
协议(该协议定义了运算符函数,运算会在这个函数中用到)。
6.Swift 标准库的许多函数和类都使用了泛型。Array
和 Dictionary
就是两个泛型集合。
7.编译器有时也无法推断出正确的类型信息,这时你可以显式指明值的类型,比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| protocol Speaks{ func speak() -> String } struct Duck: Speaks{ func speak() -> String{ return "quack" } } struct Dog: Speaks{ func speak() -> String{ return "bark" } } let fido = Dog() let donald = Duck() let pets = [fido, donald] let pets: [Speaks] = [fido, donald]
|
8.闭包提供了一种创建自包含代码片段的函数式方法,同时还能从上下文中自动捕获值。闭包一次取义于”从上下文中捕获变量常量”,即”封闭”值的意思。Swift 的闭包类似 Objective-C 中的块(block),只不过在使用上更加灵活。
9.闭包有三种不同的形式:全局函数、嵌套函数、闭包表达式,每一种都有各自的用途。
10.闭包表达式提供了一种轻量级的隔离代码的方法(不需要对代码块进行命名),同时从上下文中捕获值。下面是一个闭包表达式的例子:
1 2 3 4 5
| var aFewNumbers = [1, 2, 3] var squares = aFewNumbers.map({ (num: Int) -> Int in return num * num })
|
11.Swift 中的元组,是一种轻巧实用的数据结构,允许你将多个值结合成一个对象。
12.要访问元组的成员,你可以通过索引或者将远足分解到多个变量中。例如:
1 2 3
| let iceCreamCone = (2, "chocolate", "cone") print("I'd like \(iceCreamCone.0) scoop(s) of \(iceCreamCone.1) in a \(iceCreamCone.2)")
|
13.也可以在创建元组时,为每个成员进行命名,以便通过名称来访问元组成员,这种方法能清楚的描述元组所储存的数据,对于简单的类,可以直接用元组代替。
1 2 3
| let iceCreamCone = (scoops:2, flavor:"chocolate", style:"cone") println("I'd like \(iceCreamCone.scoops) scoop(s) of \(iceCreamCone.flavor) in a \(iceCreamCone.style)")
|
14.返回值可以指定名称也可以不指定名称:
1 2 3 4
| func numberCounts(nums: [Int]) -> (Int, Int) func numberCounts(nums: [Int]) -> (even: Int, odd: Int)
|
15.如果元组中的某个值你不需要,在分解时你可以用下划线 _
替代。
16.在 Swift 中,switch
结构,如果你需要代码贯穿到下一分支,你必须显式地实用fallthrough
关键字。例如:
1 2 3 4 5 6 7 8 9 10 11 12
| func colorForIndexPath(indexPath: NSIndexPath) -> UIColor { switch (indexPath.section){ case 0: fallthrough case 2: fallthrough case 4: return UIColor.blueColor() default: return UIColor.whiteColor() } }
|
17.在 case
中实用 where
子句,这为 switch
语句提供了更多的灵活性。你还可以在 case
语句中使用值绑定,从而使代码更加紧凑,可读性更好。如:
1 2 3 4 5 6 7 8 9 10 11
| let indexSizeAndValue = (9, 10, "") switch indexSizeAndValue{ case (0,_,let value): print("The first value is \(value)") case let (index,size,"") where index == (size - 1): print("The last value is empty") case let (index,size,value) where index == (size-1): print("The last value is \(value)") case let (index,_,value): print("The value at index \(index) is \(value)") }
|