Chris Lattner 访谈录

2017年09月,Swift编程语言开发者克里斯·拉特纳(Chris Lattner)接受某媒体访谈。

以下为访谈实录:

自我介绍

1. 你怎么看待自己?

我是个程序员。我喜欢写代码。我编程有很长时间了。

我在读博的时候就开始写 LLVM 了。当时 LLVM 是我的博士研究项目,我想把它做成工业界中颠覆性的产品。当时我异想天开,尝试了各种架构设计,想解决以往编译器所有的弊端 -- 结果当然没有如愿。我毕业后,就希望能接着搞 LLVM ,当时只有苹果允许我入职之后继续设计并实现 LLVM 。我想都没想就加入了苹果。

​​​​​​​

LLVM

2. 说说 LLVM(Low Level Virtual Machine)到底是什么吧

先说编译器:编译器是把程序员的代码翻译成机器可以理解的语言的工具;

再谈LLVM:一个模块化和可重用的编译器和工具链技术的集合,Clang 是 LLVM 的子项目,是 C,C++ 和 Objective-C 编译器,因为多模块的复用,所以提供了惊人的快速编译,比 GCC 快3倍。

3. LLVM 是一开始就作为一个完整的编译工具来使用的吗?还是有什么其他故事

LLVM 当时是为了解决一个小问题而开发的:当使用OpenGL 函数库的时候(Mac OS 10.4 和 10.5环境下),比如你要调用这个函数,glVertex3f(),编译器必须将其转化为特定的GPU可以理解的数据。但是这带来一个问题:市面上有海量的GPU,每个GPU的性能和参数也不尽相同,所要求的数据格式也不同。这时 LLVM 可以产生很小的一部分代码去解决这个问题,这是 LLVM 诞生的初衷。

4. LLVM 的 bytecode 和 Apple 现在的 bitcode 有什么不同?

这是历史遗留问题。一开始 LLVM 是开源的,所有代码在转成二进制时就叫做 bytecode -- 因为 java 当年就是这么叫的。当时这一部分有很多问题:比如不能扩展,无法兼容,非常脆弱。

然后就到了 LLVM 2.0,当时我重新设计了架构,采用的就是 Bitcode 机制。LLVM 2.0 将所有代码以比特流(bit stream)而不是字节流(byte stream)的形式来编码。这就是 bitcode 这一术语的由来。

主要的工作流程就是现将代码转成比特流,然后相应处理。处理完后再将编码传到其他地方去。

5. Bitcode 这个机制比直接传输二进制有什么好处

好处那是多了去了。首先 编译器工作起来会越来越好。因为通过Bitcode机制,它可以通过编译不同代码来存储各种优化方法,这样下次碰到类似代码,它就会自动启动相关优化机制,使得效率提升。还有个好处是 LLVM 可以让芯片的兼容性变得很好。因为 Apple 每年都在芯片上推陈出新,它们转化为二进制的规则都不尽相同,LLVM 只要每次重新编码并传输成比特流就好了。

当然 Bitcode 也不是万能的。比如它不能解决 32位的 APP 在64位机器上的兼容问题。这个问题其实应该依靠代码逻辑。

谈管理

6. 在职业生涯中,你在 LLVM 上鞠躬尽瘁,但我们发现这几年你更多的工作是在管理上,你自己怎么看这种转变的?

我虽然做管理了,但是我依然喜欢写代码,而且我每天都写,因为我就是个极客嘛。而且,其实我很早就开始做管理的工作了。不过我一直是作为技术领导人的角色带 2 到 3 个人的,我只是在写代码方面把把关,给他们提提建议这样。

后来带的人多了,队伍也大了。我不仅管程序员,还管小组经理和其他技术领导人。虽然我一直喜欢写代码,但是管理对我来说是一个必须要去做的事。现在回过头来,我觉得干得还不错。跟大家一起工作之后我知道很多事协同工作效果更好,和同事交流你就会理解他们的想法,这样我就可以制定更好的计划路线。

其实我没感觉整个过程有什么不同。直到今天我还夜以继日、废寝忘食得写代码,我并不是坐那边动动嘴皮子,指挥别人干活的老板。我其实每个周末都在写代码,我很忙的。

Swift

7. Swift 是如何诞生的?在苹果这样一个大厂,决定做出如此巨大的变革,同时还是在封闭的环境下,你是如何一步步实现的?

首先,苹果内部所有的项目都不尽相同 -- 工作流程、战略规划、实施细节,到最后发布。Swift 也一样,没有可比性。因为苹果本身就是小组单兵作战模式 -- 每个组负责不同的大方向,组里自己计划和工作,甚至招人都是各自招。

言归正传,契机发生在2010年了。当时好像是我们刚刚完成了 Clang 对 C++的支持。你也知道 C++ 写起来有多丑,但是做个编辑器支持 C++,完善 C++ 这门语言就是另一回事了,我们当时搞了好久终于完成的时候特别有成就感。当然 Clang 远没有到达完美的地步。

我又扯远了。除了做 Clang 以外,无论是 C语言,C++,还是 Objective-C,都有一些我不是很满意的地方。所以我就想要不我们搞个新的语言来吧。新的语言要越简单越好。一开始大家都没认真,后来我跟很多同事聊了之后觉得新语言的计划可行,而且大家都很亦可赛艇。于是我们就用业余时间开始顶层设计和写代码。

现在问题来了,因为我们已经有 Objective-C 了。虽然它有几个地方很丑,比如老是用 "@",每句结束了还要打分号,但是这些并不妨碍它是一门伟大的语言。所以,我们为什么要开发新语言,而不是把精力花在优化 Objective - C 上?

原因有三。

第一,如果我们大幅优化 Objective - C,把很多 Swift 的特性加进去,这对开发者来说是灾难性的,因为他们要对原来的 APP 要进行大幅修改;

第二,Objective - C 很多特性积重难返,比如它安全性上的问题;

第三,Objective - C 是基于 C 开发的语言,所以你无论怎么优化,它必然有 C 语言自身的缺陷。

于是我们就动手做 Swift 了,它的背后有着数百人的努力: 支持 Xcode,开发 Playground,兼容调试器和编译器。我个人感到最骄傲的一点是,我们并不打算自己内部把它做到完美 -- 我们开源、我们依靠社区,这样一门语言才能在无数开发者的实战中得到检验和改进,我想这才是 Swift 最棒的地方。

8. 你之前在优化 Objective-C 的时候,有没有想到什么地方是未来 Swift 可以用得到的?

ARC。我们其实一直都在争论是用垃圾回收机制(garbage collection)还是 ARC,后来决定了是 ARC。

另一个是模块化,我们也将这一部分的经验带到了 Swift 开发中。

其实,很多数组和字典方面的语法优化本来是计划在 Objective - C 上面的。但是后来我们开发了 Swift,于是这些改进被直接用在了新语言上,所以大家会在写 Swift 的时候觉得似曾相识,因为本来这些就是 Objective-C 的升级版本嘛。

我可以透露一个有意思的事情。我们在做 Swift 的时候,很多 iOS 开发者,包括苹果内部的工程师,都在吐槽我们这几年在 Objective - C 上毫无建树,都在说你们为什么不做这个那个。我们当然不能告诉他们我们在全力开发 Swift,而他们所要的语法功能我们都会给。

9. 苹果内部对于 Swift 的使用情况和开发是怎么看得?

Swift 团队对于开发上有明确的目标和计划,应用二进制接口(ABI)的稳定性一直是我们的首要目标。很多人很喜欢我们开源的 Swift Playground。同时 iOS 系统内置的 Music App 也是 Swift 写的。其实用不用 Swift 主要是技术和开发方面的考量,苹果内部同时得兼顾稳定性和开发效率,这不是说大家喜不喜欢这个语言的问题。

Swift 刚发布的时候,内部很多组都很惊讶:我们已经有了 Objective-C,为什么还要搞新的 Swift?而且 Objective-C 本身就很不错,开发起来也很顺手。后来渐渐 Swift 成熟了,大家也爱上了这个新生儿。

内部其实对于 Swift 一个很大的顾虑在于,苹果的所有开发必须兼容32位机器,而32位的应用都采用了 Objective-C 的 runtime 机制。这就要求 Swift 团队也弄出个类似的机制,或者弄个兼容的方案,否则 Swift 无法与 AppKit 适配。

10. 开源后的 Swift 发展态势喜人,你对此有什么看法?

开源之后,Swift 发展之好让我咋舌,然而这也是问题所在。

当年我们开源了 LLVM 和 Clang,它们也发展喜人。我们的对手 AMD 们完全跟不上我们。但是跟 Swift 比起来,它们的发展也太慢了,LLVM 和 Clang 开源后完全没有 Swift 这么火。

Swift 就不同了,开源一年之后,我们就有了上百万的开发者在使用这门语言 -- 我和很多有丰富开源经验的老工程师都吓了一跳,这简直了!然后我们每天收到无数的邮件和 pull requests,要求更新这个、要求优化那个,我们的节奏完全被打乱了。我们如何规划开发?我们如何把 Swift 的开发导向一个正确的方向?这些问题随着时间的推移和经验的积累,慢慢找到了解决之道。

我现在觉得开源这个决定至关重要。一来大家会帮着优化;二来我们有个巨大的论坛,在那里大家可以畅所欲言,全世界的人都在帮着 Swift 进步,这真的很棒。我们虽然没有一开始就具体计划要开源,但是苹果内部当时都觉得 Swift 肯定有一天要开源。

苹果与特斯拉

11. 苹果好像一直是个封闭的公司,你们内部对于开源怎么看?

苹果其实有开源的传统。LLVM 虽然不是始于苹果,但是最终是苹果完成并将其开源。Clang 则完完全全是生于斯开源于斯。还有其他工具,比如 LLDB,libc+,以及compiler-rt 都是如此。

所以对于 Swift 来说,开源只是时间问题。当年从 Swift 1.0 到 Swift 2.0,一切都乱七八糟。当时我们重点在开发错误处理机制,还有协议、拓展等一系列重要的功能。所以开源 Swift 1.0,并不是一个好选择,因为这些重要的东西都没有,而这些开发是当务之急。当 Swift 2.0 到来的时候,我们才有空去开源、去做社区拓展和论坛搭建。开源社区可以帮我们修复细节,我们这时候可以更多的投入在架构设计上。

12. 苹果最让你怀念的是什么?

苹果是这样一个公司,你可以选择你喜欢的东西,然后努力工作去实现它,最终你的工作会落实在产品上,影响亿万计的人。

有很多公司,你可以努力工作,但是不一定能做你喜欢的东西;你做出来东西,可能会被束之高阁;你做的产品,也许最后很幸运的发布,但是并不一定有很多人会用。在苹果,你的工作可以真正改变世界,很有成就感。

13. 你觉得到特斯拉之后,还会努力为 Swift 做出贡献吗?

特斯拉的工作非常有挑战性,这是我最开心的地方。我现在还没入职,所以也不知道我之后对 Swift 能做多少工作。也许我还会夜以继日的发 Pull Request,也许我就周末写写 Swift 代码。我应该会从各个方面 -- 无论是顶层设计还是具体代码实现,与苹果的核心团队合作,为这个语言做贡献。

其实我一直想说,Swift 只是我在苹果工作的一小部分,我花了大量的时间在其他事情上。实际上在苹果我也就晚上或者周末有空写写 Swift。我希望到了特斯拉之后我还能花同样的精力和时间在 Swift 上,毕竟我对这门语言统治世界充满期待。

ABI 稳定性

14. 现在 Swift 已经到了第3个版本了。我们也知道ABI稳定性的追求一直是你们的目标,但是它也一直被各种事情拖延。你对此有什么计划吗?或者说你从拖延中学到了什么经验教训吗?

ABI 推迟有两个原因。

第一是因为 Swift 的开发进程中有很多不确定性。当 Swift 开源之时,一堆人对我们提 pull request,提各种各样的 issue。这样我们就不得不去花大量的时间去维护开源社区,而不是专心去做计划内的工作。

第二个原因是,尽管稳定的 ABI 很重要,但是对于开发者来说,稳定的 ABI 对他们来说没有明显的好处,他们更关心是语法和兼容上的稳定和优化。所以我们后来修改了计划,语法和兼容上的稳定性被定为是最先要实现的目标。这样当 Swift 3.1 或者 Swift 4.0 出来的时候,大家不用担心语言上的转化会让 Xcode 崩溃,或是需要大家整个重构 APP。Swift 3.0 主要就是实现这个目标。

15. 稳定的 ABI 什么时候推出?他会赶在异步和并发模型之前吗?

Swift 现有的内存管理机制对 ABI 稳定性造成了不小的影响。有些底层逻辑还需要调整,比如 getter 和 setter 的生成以及属性的内存分配问题,苹果内部正在做这件事,这之后我们才能完成 ABI。至于并发模型啥的就跟 ABI 没有关系了。

很多人担心 Swift 4.0 的时候苹果能不能推出稳定的 ABI,因为毕竟工作量太大。ABI 的工作正在井然有序得进行,而且对于开源社区来讲推出稳定的 ABI 至关重要。Ted (Chris Lattner 之后的 Swift 领导人)有一件事说对了,现在 Swift 当务之急就是让编译器更稳定,让错误处理更方便,提高编译速度,并且将 Swift 拓展到大规模系统中。

我在想 Swift 4.0 的时候究竟能看到什么。也许没有稳定的 ABI,但是一定会有重要的新功能加入。

ABI 将允许未来 Swift 版本开发的应用程序和编译库可以在二进制层次上与 Swift 3.0 版本的应用程序和编译库相互调用。这样,ABI的稳定性将保证一定程度的二进制兼容性,并且第三方更容易发布二进制库。另外,ABI 将允许删除需要的 Swift 标准库和二进制文件,就像目前情况下通过Xcode创建的 iOS 和 OS X 应用程序一样。

补充

LLVM

补充:LLVM的三层结构

第一层:Clang 编译器,负责编译各种语言

第二层:代码优化器,通过模块化操作优化代码,是 Bitcode 逻辑的主要部分

第三层:代码翻译器,针对不同平台和 GPU 将代码翻译成机器语言

补充:LLDB,llbc++,compile rt

LLDB: 一个有着 REPL 的特性和 C++ ,Python 插件的开源调试器。LLDB 绑定在 Xcode 内部,存在于主窗口底部的控制台中;

libc++,libc++ ABI: 高性能 C++ 标准库实现,支持 C++ 11

compiler-rt:为 LLVM 和 Clang 设计的编译器扩展函数库。针对 __fixunsdfdi 和其他目标机器上没有一个核心 IR (intermediate representation) 对应的短原生指令序列时,提供高度调优过的底层代码生成支持。

ABI 是什么?

Application Binary Interface,中文名:应用二进制接口。是 APP 和 操作系统、其他应用之间的二进制接口。它包括以下细节:

数据类型的大小、布局和对齐;

调用约定(控制着函数的参数如何传送以及如何接受返回值),例如,是所有的参数都通过栈传递,还是部分参数通过寄存器传递;哪个寄存器用于哪个函数参数;通过栈传递的第一个函数参数是最先push到栈上还是最后;

系统调用的编码和一个应用如何向操作系统进行系统调用;

以及在一个完整的操作系统ABI中,目标文件的二进制格式、程序库等等。

Swift 在系统、服务器、网页端的发展

16. Swift 在服务器,或者 Linux 上可以说运行得不错。你们是一开始就计划在服务器或者系统端运行 Swift,还是说你们更希望 Swift 专注于 iOS 开发,而不是去与 python 或 Rails 竞争?

你如果去看苹果官方的 Swift 书,里面有这样一句:“Swift 的目标是,上能写应用程序,下能写操作系统(Swift was designed to scale from hello world to an entire operating system)”。所以我们一开始,就是要将它创作成为一门一统天下的语言。

这也许有点痴人说梦,但是大家等着,过几年就知道了。无论是我还是苹果的其他人,都把 Swift 当成是未来世界的主流语言来看的,它将会超越 Python,甚至有一天取代 C。那么我们是怎么实现这一步的呢?

开源是重要的一环。你不开源,别的平台就不大想用这个语言。当各种各样的开发都采用 Swift ,Swift 一统天下的目标也就越来越现实。现在很多学校的计算机基础教育就在教 Swift,它越来越流行了。

所以嘛,第一步我们就是让这个语言流行起来,让大家使用它。我对“流行”的定义是,Swift 必须要有一个杀手级的产品,这样大家就会知道 Swift 有多好,大家都会使用它。现在 iOS 平台和 Mac OS 平台有很多非常棒的 Swift 应用。这样我们开始第二步,开源。第三步,我们要走得更远。

什么叫走得更远?我觉得现在我们要做的就是把 Swift 应用到服务器端。其实服务器和移动应用开发颇有类似,比如架构设计和函数库调用上。但是,唯一的麻烦就是我们得让 Swift 能在 Lunix 上流畅运行。同时构建大量服务器端的库函数。现在 Swift.org 上已经有专门的版块讨论服务器端上的开发了,大家集思广益的感觉非常好。

再接下来,Swift 要取代 Java,无论是脚本语言还是底层的系统设计,Swift 最终都应该能应付自如。

脚本语言上,开源社区和我们苹果内部都在尝试将正则表达式、多行字符串等脚本语言的特征都加入到 Swift 当中,虽然工作量很大,但我认为它们最终都将成为 Swift 的一个部分。

系统开发方面,我觉得取代 Java 最重要的一点就是 Swift 一定要有自己的特色。我觉得 Rust 是一个不错的语言,虽然现在没多少人用。Swift 在某些顶层开发上要明显优于 Rust。再等过些年,当 Swift 在系统开发上真正流行起来之时,Swift 就离一统天下不远了。

17. 对于 Swift 在服务器上的发展,你觉得交给开源社区去做就足够了吗?苹果自己会不会推出面向服务器端的 Swift 函数库?

首先我觉得若要成为服务器端的流行语言,这几个部分 Swift 必须具备:编码和解码,网络传输协议,HTTP。这些部分我觉得要成为标准函数库,因为它们是最基本的东西,苹果内部自己来做也许更好,因为能确保质量。对于具体的网络应用函数库,我觉得短期内没必要。这是因为业界内部对此就争议很大,如同 Ruby on Rails 那样的王者框架还没有出现。

我觉得对开源社区而言,最重要是两个工作。第一,是 Swift 的包管理器(Package Manager)。这个可以让我们在多个平台、不同函数库之间协同工作,大幅提高兼容性和效率;第二,是并发模型(Concurrency Model)。Go 语言之所以在服务器和云端开发这么受欢迎,就是因为并发模型做得好。并发模型应该会集成在 Swift 5 中。

18. 现在 Swift 在服务器端还不是那么成熟。有人说 Swift 不过是写 App 的一门语言。现在已经 3.0 版本了,大家貌似都还只是将 Swift 用来写写 iOS 应用。你怎么看?

我现在根本不担心 Swift 在服务器端最后不会成功。很多人写了几年 Swift,自以为很懂这门语言。当 Swift 具备服务器端特性的时候,苹果一定会跟大家说,你看 Swift 能做这个那个,你用其他语言来写就要麻烦得多。

现在最大的问题是大家还觉得 Swift 只是苹果自己搞出来的东西。他们觉得 Swift 不过是苹果自己的玩具,只能用在苹果自己的 iOS 系统和 Mac OS 系统上。所以我们应该加大开源和构建社区的力度。现在外行对于 Swift 的态度还可以接受,慢慢地 Swift 就会在系统开发领域追上来。

19. 大家似乎都在期待 Swift 能在网页开发上有所建树。现在网页或者网络程序开发方面,一般是多种语言混用,前端和后端可能语言逻辑完全不一样,你对此怎么看?

这可能要花很长时间,要是能取代 Java 那就简直了。现在 Dart 在网页开发上做的不错。我个人看好 asm.js 和 WebAssembly,它们都是通过 LLVM 编译的,跟 Swift 一样。如果这两个今后做得足够好,也许就没 Swift 什么事了。未来之事,都很难说。

而且我现在发现,Java 已经变成一门基础语言了。我看很多脚本语言现在都直接编译成 Java,Java 就像比特一样成为一个最基本的表达方式。我觉得五年之后,很有可能 asm.js 会一统网页端。虽然大家说 Java 不好 debug,但其实就算你写 C 这么成熟的语言,debug 起来依然很头疼。这也是我们为什么不在 Swift 中加入宏定义,因为那个给编译和 debug 增加了难度。

Swift 语言设计

20. Swift 好像一开始就设计得简单易懂、而同时又有很多高阶的复杂操作。经验丰富的程序员可以写出漂亮的语法糖,对编程一窍不通的小孩也可以玩转 Playground。你认为 Swift 是一门将复杂和简易融为一体的语言吗?

Swift 在这点上目前做得还不错。但我担心开源之后大量的新功能添加进来,使得 Swift 不再简单。我一直致力于让 Swift 成为一门简单易学的语言,同时又足够强大。你想我们为什么不支持内联汇编 (inline assembly support) 这样的功能,就是只有极少数极客会喜欢。以后我们也要秉持这个原则。

一个不会写 Swift 的人。打开 Playground,敲下 “print("Hello World")”,旁边就会显示出来,这点跟 python 很像,你不用去打"n"这样的换行符号。也就是说 Swift 对于新手来说非常友好,我们可以从 Hello World 开始逐步深入,从简单慢慢过渡到复杂。

对于系统开发而言,Swift 相比 Rust,会更好的自动控制内存分配,因为我们可以借鉴开发 ARC 时的经验。你想内存分配这种底层的东西,也只有少数大牛能精通。那为什么不把 ARC 引入到底层来简化开发呢?我觉得这是 Swift 开发的另一个方向。

21. 有人说 Swift 是大杂烩,一部分借鉴 C#,一部分借鉴 Java,一部分借鉴 Objective-C,你是怎么看的?

Swift 确实是大杂烩。但是它并不是简单的模仿其他语言,而是借鉴,然后创造出一个伟大的语言。我们确实参考了大量其他的语言设计。比如 Haskell 很多概念就被引入到 Swift 中。Swift 中的 Protocol,就是从 Haskell 的 construct 中得到启发的。

还有其他部分长得像 Dart,亦或是借鉴了 Go 和 C#。这样做也有另一个好处,开发者拿到 Swift 的时候会有种似曾相识的感觉,这样大家也更愿意用 Swift 开发。

Swift vs. Objective-C

22. 给我个现在就学习 Swift 的理由?

这个其实无所谓。我个人不觉得 Objective-C 会短期内被取代,苹果依然支持 C 和 C++,而且放弃 Objective-C 对苹果来说有百害而无一利。你不必一定要学习 Swift,Swift 只是一门更好的语言。

说到 Swift,我们给它取这个名字就意味着我们希望这门语言非常得高效。它本身设计的目的不是让你短时间内写大量代码,而是用最少的时间、最简洁的代码来完成工作。

编程其实包括方方面面,不仅仅是写代码,还有 debug,给各种系统适配,以及其他各种事情。其实开发的时间短,找 bug 的时间一般都会很长。比如在 Objective-C 中,你会花不少时间修 unrecognized-selector error,但是 Swift 从顶层设计中就排除了这类 bug。

Swift 还有其他一些好处。比如可以对字符串使用 switch...case...语句;可以使用 functional programming;可以用 enum 和 protocol。Swift 其实是一门包罗万象的语言,菜鸟和老手写出来的 Swift 可以完全不一样,这取决于经验。

我最近发现,很多 iOS 开发者会把 Swift 当 Objective-C 来写,逻辑结构完全一样,只是换个语法。其实这就意味着他们没有意识到 Swift 的价值 -- 认为 Swift 不过是 Objective-C 的替代品。当开发者深究 Swift 的语法后,他们才会意识到这是一门多么高效的语言。

23. 会不会像 Objective-C 一样,在未来 Swift 添加一些动态特性?

Swift 目前没有加入动态特性的计划。很多人问为什么 Swift 不能有响应,reflection这些特性。甚至有人写博客说,“迟早有一天,苹果要重写 Swift 的所有架构”,我每次在 WWDC 前看到这些博客都会呵呵。很多人不明白什么叫动态性,也不关心我们发布的 Swift 计划表,只是不停的写博客,预测这个吐槽那个。

我个人可以明确表示,Swift 近期内没有加入动态特性的计划。凡事有轻重缓急,我们得先处理其他事情,比如并发模型,比如在系统端上的优化,比如脚本的适配。不过以后如果有时间,Swift 会加入动态特性的,前提是我们计划表里的事情都做完了。

24. 你不担心没有动态特性,很多 Objective-C 的程序员会各种不适应 Swift,然后就放弃用 Swift 了吗?

我不担心啊。Swift 本身支持 Objective-C 上的所有特性,你只需要那部分代码使用 Objective-C 兼容,然后把它们加入到 runtime 中即可。

虽然有很多人说,我就是想写纯粹的 Swift 代码,但其实我不觉得这是一种倒退。你可以使用 reflection 模型,要用这个功能你用就是了,自己设计的代码结构自己负责。在写代码这事上,从来没有非黑即白一说,我们要做最重要的事,而不是天天在推特上开听证会。Swift 核心组做的工作就是把关 Swift 开发,把这门语言导向一个正确的方向。

Swift 编程规范

25. Swift 现在好多语法糖。怎样避免写出奇怪和低效的 Swift 代码?你觉得现在 Swift 可以称得上成熟吗?

现在正是 Swift 成熟之时。Swift 1 和 Swift 2 的时候,确实语言的变化很大,大家很头疼。但是 Swift 3.0 是一个稳定成熟的版本,它真的不错。之后的工作是在 Swift 3.0 的基础上增加新的函数库或者功能,而不是修改现有的架构。

其实 Swift 开发者也在纠结语法糖太多的问题。我听说一些人出了一些 Swift 的书籍,这很好。其实我们在设计 Swift 的时候,就考虑到语法糖的问题了。比如你写代码,把所有变量都用 var,这时候编译器会提醒你对常量使用 let。这说明一点,Swift 是鼓励 immutable 数据类型的,并且 Xcode 也会自动督促你写出更规范的代码。不过目前对于“是该用 class 还是 struct?”这类比较困难的问题,编译器还没智能到能自动检测并纠正。

26. 有些语言一开始就有设定好的语法糖和规范。为什么 Swift 没有这样,而是让开源社区去讨论?你个人对 Swift 有没有一些编程规范?

作为一个程序员,我骨子里流淌着编程规范的血液。但在 Swift 的开发过程中,我还是改变了一些固有观念。比如说,我认为所有代码代码段都应该是一个地方输入,一个地方输出。但我后来发现这样设计语言很难维护,可读性也不佳。 比如说我们设计的 guard else 语句,你一定要在末尾写上 return 之类的结束语。这就导致了一个函数有多个地方输出:你在 guard else 里 return,在其他地方也 return,不符合我原来的设想。但是如此设计会令安全性提高,因为我们把一些特殊情况给提前处理掉了。

对于空格这种格式问题,我个人倾向于空 2 格。我知道有些人喜欢空 4 格,还有人喜欢 3 格(因为他们觉得文件中不应该有 tab)。这完全是萝卜青菜各有所爱,大家对此争论不休,哪一种都有一定道理。所以我们最后也没有对 Swift 提出固定的格式要求,大家写出自己喜欢的代码就行。但是这也造成了一定程度的混乱 -- 你写的代码格式会与同事的完全不同。但是我觉得这并不会影响语言的多样性。

Go 当年强行推广了一套编程规范,结果到现在仍有争议。我们现在的工作不是做语法上面的规范,而且我们也不希望推出一套规范后大家好不买账。开源的另一个好处是,大家可以自行决定什么是好的语法规范。就算有时间我个人或者 Apple 也不会去写 Swift Style Guide。比起规范我更愿意去回答理论和语言设计上的问题。

有一件趣事我想分享,我一直担心别人会问,为什么 Swift 的函数名叫 func?而不叫 function 或者 fn?这其实颇有争议。不过现在已经是 Swift 3.0 时代了,大家这样用得很顺,我们也不会去更改了,所以争论于此没有意义。

RxSwift 以及响应式编程

27.很多开发者用 RxSwift 或者其他响应式编程。你在开发 Swift 过程中有没有仔细研究过响应式编程这些?

我已经开始关注 RxSwift 了。但是我自己没用响应式编程来开发过产品,所以我对它们的理解来自于博客。RxSwift 看起来很棒,你可以少写很多代码,而且似乎开发效率也会更高。但听说维护和测试起来也很难,有优点也有缺点。

如果我有空写一个 App 的话,我肯定回去试试 RxSwift,然后再过来发表观点。我现在不敢说”强烈推荐”,或者“强烈不推荐”之类的话。

Garbage Collection vs. ARC

28. 我们都知道 Garbage Collection 和 ARC 各有千秋。Objective-C 有 Garbage Collection,后来加入了 ARC 的机制。Swift 则是完全 ARC。你能说说为什么你们那么看好 ARC 吗?

Objective-C 最开始是基于 Libauto 系统开发的,而 Libauto 本身就有诸多限制,所以我们当时采用了 Garbage Collection。我个人觉得 ARC 完全要优于 Garbage Collection,因为后者经常在内存上回收一下我们不想回收的变量。所以我们在 Objective-C 上采用了引用计数和 ARC。

ARC 最重要的一个优势就是,它很好的处理了 final 这类参数。如果你用 Garbage Collection,比如 java 吧,final 参数就是那些不被回收一直在跑的东西,这样展开讲问题是一箩筐。我举个最简单的例子,当有个 final 变量运行在一个错误的线程上时,它会多次重跑,导致实例被不停的创建。ARC 则是从根本上解决了这个问题。

目前反对 ARC 的理由主要有两个,一是人们觉得 ARC 引入了额外的开销,因为你要维护引用计数嘛。另一个是 ARC 容易造成循环引用。

我个人要强调的是,这些毛病 Garbage Collection 也有。除此之外 Garbage Collection 还不能终止所有的线程,或者在特定的一个时间点终止一个线程。这是因为 Garbage Collection 引入了安全指针(safepoint),这同样也是一笔额外的开销。

ARC 中引用计数的开销在实际开发中影响不大。而且我们对对象的整个生命流程都有掌控,而这是 Garbage Collection 不具备的。实际上我觉得 ARC 中有些额外开销是必须的,那些不必须的开销以后也会慢慢改进的。

至于循环引用的问题。相比于你必须在具体的一行说明,retain/malloc 这个变量,然后再在后面某一行说明,release/free这个变量这种麻烦事,你只需要用 strong 或者 weak 表示你对对象的所有权,你省去了大量思考内存分配的担忧和操作,这难道不是一个巨大的进步吗?

身后之事

29.把 Swift 交给 Ted 你放心吗?

完全不用担心。

Ted 这人实力非常强。斯坦佛的博士生毕业,苹果十年工作经验,曾经以一己之力完成了 Clang 的静态分析器。Ted 在管理方面也很优秀。我有时候会突发奇想,让手下一个人或者一个组去做“我认为有意义”的项目。Ted 则是非常稳健的管理者,他总会领导组员去做最重要的事情,这就是我跟他的不同。

另外我们的小组也很强,核心团队的几个人:Doug Gregor, John McCall, Joe Groff, Dave Abrahams。这几个人都是极其优秀的极客。Swift 其他团队的工程师也很给力。有他们在,没有任何理由 Swift 不会成功。

30. 你为什么去做电动车?

首先我个人非常喜欢车。但我又懒得自己老是去加油啊、开车,我更喜欢一种更可靠的方式,最好我自己啥也不用做,车子就可以把我送到目的地。我也不需要担心维护啊什么的。我其实是特斯拉最早的一批客户,我觉得特斯拉驾驶起来很开心。

不过我重来没想过我会去一家汽车公司任职,因为我觉得我是个程序员,这跟汽车有啥关系?不过特斯拉让我去做自动驾驶系统,这个就很对我胃口了。因为这也是世界级的难题,我想尝试挑战一下。

——翻译作者:@故胤道长,亚马逊 iOS 工程师,曾就职于 Uber

相关领域
人物