[译]Swift 的类型体系
Brent Simmons 在 解决目前不存在的问题,就好像问题存在一样 中说到:
Swift 的类型体系解决了我没碰到的一个问题。
对这句话我深有同感,而且我敢打赌很多其他的 Objective-C 开发者也会这样觉得。
在我刚开始尝试使用 Swift 时,编译器似乎经常和我做对 1 。但随着我对这门语言越来越熟悉,情况也随之变得好起来,但是有时它奇怪的错误信息还是会让我觉得它是一个难以取悦的任性小孩。
在这样的情况下,Swift 严格的类型检查所带给你的好处相比你为了让代码运行所付出的努力就少之又少了。即便如此,它的类型体系还是在去年成长到了让我再也不想错过它的程度。
Swift 更好理解
相比 Objective-C 我更喜欢 Swift 最大的原因不是他的类型体系,而是一些更平凡的特性
- 一等公民值类型。可以把
integer
或者struct
在不使用object
包装的情况下就放到array
中,这可以说是大赢,因为这意味着我们可以对这些类型进行扩展。 - 枚举有关联值。还有元组。在 Swift 中构建数据结构模型变得更加清晰。
- 模式匹配。
- 更清晰的语法且没有头文件。
简而言之,Swift 是现代语言,而 Objective-C 显然不是。
如果 Apple 在去年发布了真正的 “Objective-C 3.0”,在保留 Obj-C 动态特性的情况下使其现代化 2 ,我将会更加开心并且可能永远不会主张更加静态的类型检查。毕竟,“我知道我所做的事情,而且我永远不会因为数组里面包含意外类型而导致错误。”
Hole-Driven 开发
但是 Apple 给了我们 Swift, 而不是 Objective-C 3.0。Swift 的发布促使我去了解其他有同样类型体系的语言,比如 Haskell,ML 和 Scala。我从那些社区学到的特别的一点就是 hole-driven (或编译驱动)开发 :不要把编译器当作需要你对抗的一股力量,而是把它当作可以解决你问题的一件神器,根据类型一步一步滴来。
Hole-Driven 开发在构建数据结构模型和数据转换时可以说是梦幻般的技术( Haskell 和它的同类尤其擅长),而且尽管还有可提升的潜力,它在 Swift 中依然表现滴相当棒。烦人的编译器和有益的编译器最关键的不同点在于它的错误信息是不是易于理解,而很多 Swift 的诊断信息仍然相当神秘 3 。
对于典型的 GUI 编程, 编译驱动开发可能没那么有用,尽管我认为这主要归根于 Cocoa API 的设计而不是编译驱动开发固有的限制。像 ReactiveCocoa 这样的库就向我们展示了类型体系(在一定程度上说应该是清晰的语法)设计出来的 API 是什么样的。当你可以依赖一个幸亏有泛型的编译器来做多步的 复杂信号变换 ,保证结果的正确性将会变得更加简单。现在我发现在 Objective-C 中写这样的代码要难得多(随后也更难理解),因为我需要在我脑海中记更多的东西。
自动文档
严格的类型体系带来的另外一个巨大好处就是做为副产品生成的自动文档。做为 Apple 平台上的开发者,我们访问不到我们最常使用的库的源代码,所以我们需要依赖文档。编译器强制 API 设计者提供的信息越多,使用 API 的人就越方便。单可选注释就给 Cocoa 的文档提供了极大的提升 4 。想象一下如果所有 Cocoa 的 API 的方法参数和返回值类型都是 id
。头文件基本上就没什么用了。
总结
在强制我自己对类型进行非常仔细的思考之后,我发现我 Swift 代码的设计更好了,也更容易维护了。我对我代码的正确性也更加有自信了,而且更奇怪的是:写起来也更有趣了!(PS:此处有强烈的补肾丸广告即视感)
Swift 仍然在起步阶段。有时它可能会让你沮丧,但是随着时间的推移编译器提示的错误信息会更友好,甚至可以让你的代码更加合理。比如说我们都在纠结的一个例子,并发:如果编译器可以静态滴证明你的多线程代码不存在冲突,那就是一个巨大的优势。Swift 现在还不能做,但是 Rust 可以 。对次我相当兴奋。
<a name="1">1.这也是我觉得 Swift 果断不是一门易学(易教)语言的原因之一。另外一个就是复杂的标准库</a>
<a name="2">2.我们几十年来都在使用“没有 C 的 Objective-C”,而是以 Smalltalk 的形式</a>
<a name="3">3.毫无疑问,至少有一部分原因是我对语言比较陌生</a>
<a name="4">4.我需要提醒大家的是注释是不保证正确性的,所以严格滴说它们没有头文件注释可靠。也许有人会认为仅仅一个严格的编译器就可以强制让 Apple 的文档更加精确。</a>
更多建议: