苹果新贵Swift之前世今生
2010年的夏天,Chris Lattner接到了一个不同寻常的任务:为OS X和iOS平台开发下一代新的编程语言。那时候乔布斯还在以带病之身掌控着庞大的苹果帝国,他是否参与了这个研发计划,我们不得而知,不过我想他至少应该知道此事,因为这个计划是高度机密的,只有极少数人知道,最初的执行者也只有一个人,那就是Chris Lattner。
从2010年7月起,克里斯(Chris)就开始了无休止的思考、设计、编程和调试,他用了近一年的时间实现了大部分基础语言结构,之后另一些语言专家加入进来持续改进。到了2013年,该项目成为了苹果开发工具组的重中之重,克里斯带领着他的团队逐步完成了一门全新语言的语法设计、编译器、运行时、框架、IDE和文档等相关工作,并在2014年的WWDC大会上首次登台亮相便震惊了世界,这门语言的名字叫做“Swift”。
根据克里斯个人博客(http://nondot.org/sabre/)对Swift的描述,这门语言几乎是他凭借一己之力完成的。这位著名的70后程序员同时还是LLVM项目的主要发起人与作者之一、Clang编译器的作者,可以说Swift语言和克里斯之前的软件作品有着千丝万缕的联系。
同样是70后程序员,差别怎么那么大呢?
关于作者
克里斯可以说是天才少年和好学生的代名词,他在2000年本科毕业之后,继续攻读计算机硕士和博士。但克里斯并不是宅男,学习之余他手捧“龙书”游历世界,成为德智体美劳全面发展的好学生。之后就是一篇又一篇地发表论文,硕士毕业论文即提出了一套完整的运行时编译思想,奠定了LLVM的发展基础,读博期间LLVM编译框架在他的领导下得到了长足的发展,已经可以基于GCC前端编译器的语义分析结果进行编译优化和代码生成了,所以克里斯在2005年毕业的时候已经是业界知名的编译器专家了。
注:很多计算机专业的大学生经常问我在大学里学点什么好,看看克里斯就行了。以目前的科技信息开放程度,如果你在自己感兴趣的领域里用心耕耘,再加上那么一点点天分,毕业时成为某一个专有领域的专家应该不是问题。那时就不是你满世界去找工作了,而是工作满世界来找你!
克里斯毕业的时候正是苹果为了编译器焦头烂额的时候,因为苹果之前的软件产品都依赖于整条GCC编译链,而开源界的这帮大爷并不买苹果的账,他们不愿意专门为了苹果公司的要求优化和改进GCC代码,所以苹果一怒之下将编译器后端直接替换为LLVM,并且把克里斯招入麾下。克里斯进入了苹果之后如鱼得水,不仅大幅度优化和改进LLVM以适应Objective-C的语法变革和性能要求,同时发起了Clang项目,旨在全面替换GCC。这个目标目前已经实现了,从OS X10.9和XCode 5开始,LLVM+GCC已经被替换成了LLVM+Clang。
Swift是克里斯在LLVM和Clang之后第三个伟大的项目!
关于语言
2007年之前,Objective-C一直是苹果自家院落的小众语言,但是iOS移动设备的爆发让这门语言的普及率获得了火箭一般的蹿升速度,截止到今天,Objective-C在编程语言排行榜上排名第三,江湖人称三哥,大哥二哥分别是C和Java这样的老牌语言。同时,苹果在2012年和2013年分别对Objective-C进行了大规模的优化和升级改进,增加了各种现代语言的特性,让编写App更加容易,更多的程序员投入到了App Store的生态圈里……
在这种情况下,苹果公司为什么会发布一门新语言呢?
这个问题没有标准答案,不过我们可以试着去分析一下,谈谈苹果的心路历程……
Objective-C是21世纪80年代初由Brad Cox和Tom Love发明的,1988年乔布斯的NeXT公司获得了这门编程语言的授权,并开发出了Objective-C的语言库和NeXTSTEP的开发环境。后来NeXT被苹果收购,Objective-C阴差阳错地成了苹果的当家语言。掐指一算,30年倏忽而过,OC也成长为爷爷辈儿的编程语言了。
为了伺候好这位“爷爷”,苹果煞费苦心,把GCC的编译链先替换成LLVM+GCC,又替换成LLVM+Clang,做语法简化、自动引用计数、增加Blocks和GCD多线程异步处理技术……终于,OC在30年后重新焕发出勃勃生机,并占据了兵器谱排名第三的位置。但是,苹果却有点烦了,OC改进了这么多年,怎么看都像是在修修补补,用Blocks去实现一个类似Python的Lambda闭包功能,看起来总是那么别扭。好吧,既然已经全盘掌握了LLVM和Clang,为什么我们不去基于现在的编译器设计一门全新的语言呢?一门属于苹果的语言!你看,邻居谷歌家里叫做Go的孩子不是玩耍正酣吗?
于是Swift诞生了……
当然,事实的真相也可能是行动缓慢的乔老爷子把克里斯拉到一边说:
“I want to be swift to...”
“行了,您别说了,不就是想要Swift吗,我这就给您做一个去。”
于是Swift诞生了……
语法
Swift是一门博采众长的现代语言,在设计的过程中,克里斯参考了Objective-C、Rust、Haskell、Ruby、Python、C#等优秀语言的特点,最终形成了目前Swift的语法特性。我在阅读了官方教程和做了些代码实验之后,自我感觉会喜欢上这门语言,在这里简单谈点感想,更深入的内容需要你们自己去深入学习。
1.Swift是面向Cocoa和Cocoa Touch的编程语言,编译型语言,生产环境的代码都需要LLVM编译成本地代码才能执行,但是Swift又具备很多动态语言的语法特性和交互方式。
2.Swift是一门类型安全的语言,可以帮助开发者清楚地掌控代码片段中的值类型。如果你期望输入的是字符串,类型安全的特性会阻止开发者错误地为其传递一个整数。这一切使得开发者能够更早地发现和修复错误。
3.支持各种高级语言特性,包括闭包、泛型、面向对象、多返回值、类型接口、元组、集合等。
4.Swift能与Objective-C进行混合编程,但代码分属不同的文件。
5.全面的Unicode支持,你甚至可以用一只表情狗作为变量名,实现以下操作:
let= "大狗菠萝"
for n in{
println( n )
}
控制台会输出“大狗菠萝”四个字。
6.编程语句取消了大部分语言使用的“;”分隔符,只有一行写多条语句时才需要分号。
7.很多人简单阅读了Swift的数据类型,就认为Swift没有类似Set和List这样的数据结构,其实Swift提供了两种Collection的数据类型:数组(Array)和字典(Dictionary)。这两个数据类型的表达式都用中括号标识。其中数组可以存储任意类型的变量,也可以强制声明存储同一种类型的变量。同时数组提供了类似Set的功能,你可以修改、追加、替换和删除数据的元素。另外,Swift还提供了元组(Tuple)的功能,支持函数多返回值。
8.Swift没有提供显式的指针,参数传递根据数据类型的不同分为:值类型和引用类型。值传递进行内存复制,引用传递最终传递的是一个指向原有对象的指针。这一点和Java的参数传递是类似的。需要注意的一点是,Swift里的数组和字典虽然都是结构体(struct),但在参数传递过程中处理方式却不一样,默认Array是引用传递,Dictionary是值传递。而在Java中,由于数组和Map都是对象,所以传递的都是指针。
在Swift中,如果你不想传递数组引用,可以用copy()方法先复制一份出来,另外,也可以用unshare()表示,这个变量不传递指针。
9.闭包,Swift终于提供了一种优雅的闭包解决方案,在Swift中,函数变成了闭包的一种特殊形式。全局函数是一个有名字但不会捕获任何值的闭包,内嵌函数是一个有名字可以捕获到所在的函数域内值的闭包,闭包表达式是一个没有名字的可以捕获上下文中的变量或者常量的闭包。下面是一个闭包表达式的简要示例。
在标准库提供的排序函数sort中进行函数传递:
let names = ["D", "B", "R", "C", "A"] func backwards(s1: String, s2: String) -> Bool { return s1 > s2 } var rnames = sort(names, backwards)
事实上更简单的写法是:
var rnames = sort( ["D", "B", "R", "C", "A"] ) { $0 > $1 }
10.可选变量Optional的引入主要是为了应对一个变量可能存在也可能是nil的情况,这种情况在很多高级语言里都存在。比如你想使用String的toInt方法将String转化为Int类型,但是你并不知道这个转化是否正常,这时候系统会返回一个可选变量,如果转换成功就返回正常值,转换失败就返回nil,如下:
let str = "123A" let nn = str.toInt()
这时nn就是可选变量,想得到nn的值,可以通过if进行判断并通过追加感叹号获取变量值,如下:
if nn { println(nn!) }
可选变量的引入解决了大部分需要显式处理的异常,这部分工作也扔给编译器去做了。想了解更多可选变量的用法,请阅读苹果的官方文档。
11.Swift中的nil和Objective-C中的nil不同。在Objective-C中,nil是指向不存在对象的指针,而在Swift里,nil不是指针,它表示特定类型的值不存在。所有类型的可选值都可以被设置为nil,不仅仅是对象类型。
12.Swift没有从语言层面支持异步和多核,不过可以直接在Swift中复用GCD的API实现异步功能。另外,没看到Swift的异常处理机制,可能有了可选变量,异常的使用会非常少吧。
关于语法相关的内容,先写这么几点吧。
给大家推荐一篇王巍(@onevcat)写的《行走于Swift的世界中》,深入阅读必有收获:http://onevcat.com/2014/06/walk-in-swift/。
基本上,Swift绝对不是玩具语言,而是一门可以被大众接受的工业级编程语言。相信假以时日,Swift必将在App开发领域大放异彩。
性能
Swift在WWDC上展示出来的性能还是让人非常吃惊的,在进行复杂对象排序时,OC的性能是Python的2.8倍,Swift是Python的3.9倍;在实现RC4加密算法的时候,OC的性能是Python的127倍,Swift是Python的220倍。总之Python在某一个深坑里膝盖中箭了,OC也没好到哪去,而Swift,就是快啊就是快!
对于这一点我并不是很理解,首先是WWDC上展示的语言层面的基准测试过于简单了,另外,OC和Swift都是被LLVM编译成本地代码执行的,理论上针对Swift的优化同样可以应用于OC,但是Swift居然比OC快那么一点点,难道LLVM单独针对Swift做了优化吗?我不是很明白,但觉得很厉害。
当然,还有更较真的程序员,他在第一时间针对于循环、递增、数组、字符串拼接等功能进行了测试,发现Swift的性能比OC还是差那么一点点的(http://www.splasmata.com/?p=2798)。
无论这些测试数据是否准确,我觉得性能是我们最不需要担心的问题,苹果已经全盘掌握了这个语言的方方面面,从底层编译框架到编译器再到语言设计,优化之路才刚刚开始,我们只要给这门新语言一点耐心就可以了。
所码即所得(Playground)
对于开发者来说,Playground是本次WWDC最大的亮点。能够在编码的同时实时预览输出结果是每个开发人员的梦想,这一次苹果为大家提供了这样的福利。
Playground不仅实现了很多脚本语言支持的交互式编程,而且提供了控制台输出、实时图形图像、时间线(timeline)变量跟踪等功能,开发者除了可以看到代码的实时运行结果,还能根据时间线阅读某个变量在代码片段中值的变化。这真是太棒了!
最初看到这个功能的时候,我甚至以为每个Swift文件都可以基于Playground进行实时编码预览,仔细阅读文档后发现,只能在XCode提供的Playground文件中实现以上功能。看来Playground顾名思义,目前还只是为开发者提供了一个玩耍代码的地方。
当然不仅仅是玩耍,我们可以基于Playground做这些事情:
1.学习。通过Playground学习Swift,制作Swift教程实现交互式学习,同时还可以培训其他初学者。
2.代码开发。执行算法程序,迅速看到算法结果,跟踪变量;执行绘图程序,即时看到图像结果,及时调整。执行通用代码,查看变量的改变情况。
3.实验性代码。无需创建项目,直接打开一个独立的Playground文件即可编写代码,尝试调用新的API。
对于Playground,设计者克里斯是这样描述的:Playground功能倾注了我个人很多心血和激情,我希望新的编程语言具备更好的交互性,更友好,更有趣……我们希望通过这门语言重新定义“如何教授计算机科学!”
开始使用Swift
作为一门新语言,Swift的定位非常明确,就是吸引更多的开发者加入苹果的软件生态圈,为iOS和OS X开发出更为丰富的App,如果你是App Store的开发者,推荐尽早学习和掌握这门苹果力推的新语言。对于大部分新事物来说,越早介入,获利越多。如果你是一名Web相关的开发者,与其等待Swift增加Web开发的相关特性,还不如去学习一下Go语言Web编程。
如何开始Swift呢?
1.下载Xcode 6版本。
2.下载苹果官方提供的Swift编程语言电子书(https://itunes.apple.com/cn/book/swift-programming-language/id881256329?mt=11),中文版本(http://yuedu.baidu.com/ebook/6f6c3b1ef01dc281e43af000)。读。
3.下载WWDC Swift的Session视频和PDF。看。
4.基于Xcode 6创建Swift语言的项目,在项目中创建Playground,在其中调试玩耍。
5.根据官方提供的GuidedTour.playground学习Swift语法特性。下载地址是https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/swift_programming_language/GuidedTour.playground.zip。
6.熟悉了基本的语法特性、与OC的混用、与Cocoa和Cocoa Touch的交互、调试等功能之后,就可以构建你的第一个Swift App了。
可以说Swift是我所见过关注度最高的新语言,一经推出即万众瞩目,媒体和开发者在数天之内对Swift进行了长篇累牍的报道和讨论,英文手册迅速被翻译成中文,即使是江湖上的另一位大佬谷歌2009年推出Go语言时也没有如此浩大的声势。当然,这和Go语言的定位有关,作为一门系统级的服务器端语言,开发者的可选余地太大了,如果谷歌推出Go是用来取代Java开发Android App,那可能情况就完全不一样了。