ObjC 我挺熟悉的,但切换到 Swift 的路并不顺利,虽然我之前写过一个结合 Swift + ObjC 运行时的换肤库 LWTheme,现在看来,确实是相当 ObjC 呀。
写了一点点商业 Swift 代码后,我现在还不能说我熟悉 Swift 了,Swift 内容太多了,特别是 Enum 以及带泛型的 Protocol,抽象能力太强了。
先开始吧。
纯 Swift 相比 ObjC,类型推断能力大大加强,算是一个静态语言,没有什么动态运行时,但 Target-Action 部分,在 Switch 里面,其实还是依赖 ObjC 运行时来跑的。
带 Optional 的静态推断,最大的好处,是类型安全,带 nil 的指针不会到处飞了。一眼开过去,Swift 的语法很像脚本语言,实际使用起来,也很函数式,很多时候,确实是用更少的代码粘合了更多的功能,带来的问题是能量压缩是想当大的。
反面的例子如下:
let stringArray = ["a", "bb", "cc"]
let countsArray = stringArray.filter { $0.count >= 2 }.map { $0.count }
print(countsArray)
输出是 [2,2]
假若 stringArray 带的是其他的类型,而在 countsArray 里面的 filter、map 操作有很多,那里面一长串的 $0 看的真的让人头大,因为实际的代码可不会像上面这样只有 2 行,也不会仅仅只有一种 transform,而是各种转换带下来,表达密度真的太大了。
闭包相比 ObjC 容易写多了,但也有一些变种,比如上面 filter、map 的参数就是闭包,闭包只有一行的时候是可以省略 return 的,还有尾随闭包,比如上面的 filter 及 map,下面这个也是尾随闭包
let seq = ["A", "B", "C"].sorted { $0 > $1 }
print(seq)
输出是 ["C", "B", "A"]
不得不说 Swift 的语法有点过于自由,这些隐含的缺省用法,看代码的时候得留意了。
Swift 的 Enum 语法不仅仅是只有枚举,以及 raw value,还可以带相关值,提升为了一个带标记的容器,使得即便作为一种输入,其输入内容其实也是千变万化的,只是标记了一种路径输入而已,输入内容是带进来的,比如
enum Goods {
case name(String)
case price(Int,Int) // 任性的将小数做为单独的 Int 带入
}
除了上面,常见的例子还有定义网络请求,将部分请求参数做为相关值带进来。
struct 相比 class,不能被继承,以及都是值传递而不是引用传递,这点让人不是那么满意,虽然写代码的时候往往不会注意到这点。
因为现实世界中的结构体其实可以很大的,有时候不是刚开始设计的问题,是后续的需求催大的。
有了严格的类型推导,泛型到处都可以存在,这种抽象容器能力,是 ObjC 所达不到的了。
Swift 的 protocol 结合泛型,然后 extension 使用 protocol 将 class 能力大大扩大了,感觉就像是一种带入的计算属性一样,强。
现实中的 protocol 加上泛型,结合类实现,将类抽象为一个巨大的逻辑容器,代码真是让人看得头大,但另外一方面,不得不说如果是类似数据构建的页面,数据逻辑的抽象层让人放心了。
当然 UI 操作逻辑的抽象层也是可以做的。
相比 ObjC 运行时的无所不能,Swift 带来了严格的访问控制,open、public、internal、fileprivate、private 应该有这五种吧,让 ObjC 转行过来的同学头都大了。
--
潦草的先这样吧。