【作者简介】任敏,北京工业大学硕士,2005年加入微软中国有限公司,2009年加入腾讯,现任高级工程师,曾负责开发“QQ概念版”和“Q+”、“QQ互联”、“iPadQQ”等产品。腾讯学院讲师,专利专家。一直从事互联网领域的软件开发和生态建设。多次参加国内外互联网开发大会,在MicrosoftTechEd、Mix大会、IndustryVelocity、TopSummit、HTML5峰会等多个开发者沙龙分享。首先我们来考察一下Swift是一种什么样的编程语言。在2014年苹果的WWDC(世界开发者大会)上,Swift首次亮相。Apple宣称Swift具有三大特性:●安全(SAFE)●现代(MODERN)●强大(POWER)首先引入的安全特性是变量和常量的类型安全:例如,在下面的代码中,Swift使用关键字let声明常量,关键字var声明变量。可以在声明的时候指定常量和变量的类型,也可以不指定类型直接赋值。Swift会通过赋值的类型自动定义变量的类型。如果在没有赋值的情况下声明,每种类型的变量都有自己的默认值。例如,Double类型的变量的默认值为0。这与Objective-C、C++和C语言不同。如果不给变量赋值,变量的默认值是一个随机数。如果不注意这一点,很容易导致bug。使用Swift语言可以避免这种情况,所以Swift是类型安全的。另一个安全功能是在过程控制方面。例如,下面代码中的switch语句有2个case语句。分别代表legCount为0和1到13之间的奇数的情况。但是,除了这两种情况,legCount也可能是其他的值,比如:2或者15等等。Swift的语法规定,如果case语句不能涵盖所有可能的情况,则必须添加default语句来处理其他情况。否则编译会失败。这样就可以避免因为程序员的疏忽和流程没有经过switch-case处理而导致的逻辑错误。我们可以看到Swift中的安全特性确实帮助新手减少了bug和逻辑错误。不过,类似“变量在声明时就有初始值”的特性,已经在JavaScript、C#等现代语言中实现了。在强大的功能方面,一个特点是字符串操作的简化。在下面的代码中,Swfit可以使用\(a)的形式来代替C语言中的字符串格式化操作。大大简化了代码,增加了程序的可读性。巧合的是,在WWDC2015中,Apple为新版Safari和WebKit添加了一个针对JavaScript的新特性。这个特性可以用${variable}的符号代替传统的用“+”拼接字符串的操作。在项目实践中,类似的字符串拼接应用多为日志操作。通常,它们已被打包为组件。所以这种语法虽然可以简化代码,但是对项目影响不大。与强大功能相关的另一个特点是对Unicode的支持。比如下面的代码,可以直接使用苹果的emoji图标来写程序。每个鼠标图标都可以视为一个字符。网上有网友利用Swift的这个特性写了一个诺亚方舟的故事,另一个强大的特性就是For-in语句的增强。例如在For-in语句中使用0...4表示循环时[0,4]闭区间内的整数值。也可以在For-in中使用“元组”来遍历Dictionary。另外,用“n...m”形式表达[n,m]闭区间的语法也可以应用在switch-case语句中:以上是Apple的WWDC2014对Swift强大方面的一些介绍。但是,正如您从上面的示例中看到的那样,这些新功能更像是一些语法糖。维基百科对句法糖的定义如下:句法糖(Syntacticsugar),又译为糖衣语法,是指在计算机语言中加入的某种语法。这种语法对语言的功能没有影响,但更方便程序员使用。.一般来说,语法糖的使用可以增加程序的可读性,从而减少程序代码出错的几率。维基百科上除了语法糖外,还有“语法盐”和“语法糖精”两个概念。分别代表极其难懂的语法,和看似有用实际上有害的语法。例如,“n..m”语法可以在Swiftbeta版本的for-in语句中使用。意思是从n开始,循环m次。例如:但是在正式版中,这种写法已经被取消了。因为“n..m”和“n...m”这两种写法太相似了,如果都保留,会造成混淆,降低程序的可读性,成为“语法盐”或“语法糖精”。现在评价Swift的新语法是语法糖还是语法盐还为时过早,需要时间和市场的检验。接下来,让我们检查Swift中Modern的特性。首先是闭包。在下面的代码中,repeat函数可以接受一个闭包类型的任务参数。在调用repeat函数时,传入的第二个参数是一个函数体,里面包含一行打印语句。那么什么是闭包呢?闭包具有以下三个特点:?匿名函数(方法)?可以执行?可以作为参数传递说到闭包,很多人肯定会想到JavaScript。让我们比较一下JavaScript闭包。我们可以看到,在上面的代码中,sayAlert是一个闭包,也符合上面三个特点。其实满足以上三个特点的文法有很多,只是名字不同罢了。比如Java和C#中的Lambda表达式:这是一段C#代码,delegate关键字用来定义一个函数签名。例如,以del为名定义一个参数int返回int的函数。接下来使用Lamada表达式定义函数体为“x=>x*x”,表示返回参数x的平方。此时myDelegate可以被调用并传递,所以就变成了一个闭包。更广泛地说,C中的“指向函数的指针”也满足上述三个条件。因此,虽然闭包是现代语言的一个特性,但是很多语言都支持它,并不能算是一个很新颖的特性。另一个现代特征是“泛型”。在Swift中使用泛型非常方便,语法与Java、C#、C++非常相似。不过使用Objective-C的朋友也有福了。在即将到来的XCode7中,Objective-C也支持泛型。所以我们不必因为泛型而切换到Swift。Swift的另一个特性是“可空”变量类型,也称为可选(Optional)变量。这是一个方便的功能。例如,返回值为int的函数可以返回nil以指示该函数出错。没有必要使用NSError,也没有必要返回一些特殊的int值来指示错误,例如“-1”或“-IntMax”。然而,类似的语法出现在10年前的C#2.0中。以上是微软官网MSDN上的示例代码。可以看到双问号“??”运算符也最早出现在C#中。以上是AppleWWCD2014中介绍的Swift1.0的特性。在今年的WWDC2015中,苹果发布了Swift2.0。其中,增加了一个需求特别高的特性:通过类似try-catch的语法支持错误处理。从示例代码可以看出,Swift支持使用多个catch语句来捕获不同类型的Error。并且还支持使用finally语句。然而,WWDC2015大会PPT中的代码与微软官方文档中的一段代码非常相似:介绍了Swift的这么多特性,我们应该如何评价Swift语言呢?客观地说,Swift确实包含了“安全、现代、强大”的特性,但这些特性早已被其他语言所支持。因此,这些特性相对于其他语言(包括Objective-C)并不具有绝对优势。对于一门编程语言,除了语言特性之外,还可以从以下三个方面进行比较:?代码效率?学习成本?生态环境其中,代码效率可以分为代码“编写效率”、“编译效率”而“运行效率”如果与Objective-C相比,Swift在编写效率上胜出。在编译效率上,由于Swift没有.h头文件等一些特性,理论上比Objective-C要快。但在实际工程上,我们内部的一个iOS项目包含了数千个Objective-C文件,完全编译一次需要30分钟左右。对于这种情况,显然不是迁移到Swift就能解决的,而是需要重构。如果是小项目,编译时间差别不大。针对Swift和Objective-C的运行效率,primateLab进行了对比测试。结果如下:通过右侧平均值的对比可以看出:1.在CPU负载较重的Mandelbrot测试中,Swift取得了与C++相似的结果。2、在GEMM测试中(侧重于有限内存中大数据的顺序读取操作),Swift与C++的差距变大了。3、在FFT测试(大数组随机读取)中,C++的性能是Swift的近10倍。因此可见,从运行效率来看,Swift并不能完全胜任所有场景。总结一下:虽然Swift在代码效率的三个方面都有一定的优势,但是目前还不能下结论说“我们应该转用Swift”。我们继续从第三个方面来考察Swift:学习成本。Swift虽然属于类C(C-Family)语言,但它除了保留大括号、if-else、do-while、swich-case-default等语法元素外,也创新了许多新的语法。某些语法形式(例如枚举类型)差异很大。学习Swift语法可能比Objective-C更容易,但不会是零门槛。另外,使用Swift开发应用必须依赖Cocoa框架,这对于之前没有接触过Cocoa的程序员来说是一个很大的隐性成本。这里引用JavaEye社区创始人Robin的话,供大家参考。“对于程序员来说,熟悉Swift语法只要一天就够了,关键是要提供高级数据类型,简化Cocoa类库,否则用不用Swift都没什么区别。”Swift语言的学习成本并不像媒体宣传的那么低。所以我们还需要从第四个方面——生态环境来考察。生态环境是一个比较抽象的概念。这里我们把生态环境简化为两个问题:1、有没有很多开源项目可以借鉴?2、遇到问题能快速找到答案吗?对于第一个问题,我们可以参考Github(http://github.info)上的开源项目统计。尽管Swift在“活跃代码库”数量上相对较少,但它在“平均代码库分支”和“平均代码库追随者”数量上均处于领先地位。由此可见,斯威夫特拥有一群非常狂热的粉丝。虽然粉丝的绝对数量可能不多,但加速的趋势很大。后续发展非常值得期待。对于第二个问题“有问题能不能快速找到答案?”,可以参考Stackflow网站的一项调查。其中,JavaScript与Github一样位列语言排行榜首位。斯威夫特没有入围。但在顶级语言榜单上,Swift位列第一。再次证明了程序员对Swift的热情。基于以上两个问题可以看出,Swift很受欢迎,但目前成熟度还不够高。我们接下来看生态环境的另一个因素:框架。让我们将它与最好的JavaScript进行比较。在谷歌上搜索“JavaScript框架”,可以看到排在前列的是关于JavaScript框架对比排名、如何选择框架的文章。具体框架的引入排名第五。由于大多数人都熟悉jQuery,因此Zepto不再出现在搜索结果的第一页上。由此可见,JavaScript的创新性、活跃性和生命力是非常高的,不愧是最好的语言。相比之下,Swift只能基于一种框架——Cocoa进行开发。Swift可以说是和平台强相关的。如果没有Apple平台,Swift可能没有用。在过去的十几年里,我们看到了微软和诺基亚的兴衰。因此,当我们决定是否选择Swift时,我们对苹果的前景和信心也是一个重要的考虑因素。以上,我们从语言特性、代码效率、学习成本、生态环境四个方面对Swift进行了考察。此外,还有一些因素值得考虑。第一个是调试工具。为什么JavaScript作为前端语言如此受欢迎?一个重要的因素是,GoogleChrome和FireFox等工具为JavaScript提供了相当完善和优秀的调试工具。另一个因素是跨平台开发。我们是否愿意把自己赌在一个平台上,赌这个平台的成败。Php和JavaScript几乎没有平台的概念。但是如果是做移动开发,显然还是要选择平台。但是最近Facebook推出了一个框架:ReactiveNative。虽然还不完美,但我们可以想象一下,如果我们可以用JS开发iOS,我们还会学习Swift吗?除了开发,在实际项目中还有很多工作要做。比如测试,比如测试结果的分析,应用上线后的运行状态分析。如果很多用户上网后程序崩溃了,怎么知道崩溃的原因呢?定位问题?在腾讯内部,有一个公开的崩溃定位模块。每个应用程序都可以使用这个模块。该模块可以帮助应用定位分析崩溃的次数、类别、原因等信息。现在这个模块已经对外发布,命名为Bugly。腾讯以外的应用也可以使用该模块。感兴趣的同学可以访问http://bugly.qq.com,或者关注微信公众号:weixinBugly。以上我们对Swift做了各种分析比较。现在是时候回答我们在本文开头提出的问题了。1.我们应该开始学习Swift吗?答案是肯定的。Swift融合了现代语言的许多高级特性。通过学习Swift,你可以了解现代语言的发展趋势。多掌握一门语言,也有利于横向比较,更深入地了解语言特性的本质,也是提高自己视野和学习能力的有效手段。2.我的项目应该迁移到Swift吗?这个问题要具体情况具体分析。首先要看团队的能力。如果团队学习能力强,可以考虑使用Swift。但这不是绝对的。如果团队非常有经验,有五年以上的iOS开发历史,那你就更要谨慎了,因为这样会增加学习成本。如果团队很年轻,经验不多,可以考虑使用Swift。接下来要考虑的是项目的组成。比如C语言文件有几千个,转换成本太高。而且会严重影响应用的稳定性。如果是全新的项目,可以考虑使用Swift。从上面的分析可以看出,一门语言对项目的影响没有那么大,对程序员的职业发展也没有那么大的影响。程序员可能有很多发展方向。在这些方向中,除了关注语言、开发需求、BUG修正之外,还有很多更重要的东西。在下图中,我列出了一些开发方向和相应的程序员关注点。此外,无论我们做什么,都需要一些通用的能力,比如学习能力、分析问题和解决问题的能力、创新能力、传承知识和培养人才的能力、交际能力等等。斯威夫特是绣腿吗?斯威夫特就像一套武术招式。能不能发挥出强大的威力,不在于招式本身,而在于施法者的内功。只有当你变强了,你才能充分利用Swift的特性,做出优秀的应用。所以我们还是要关注自己的成长,多学习Swift语言之外的东西。
