如何评价 Swift 语言?

今天苹果推出了全新的基于脚本的编程语言 Swift。Swift 有类似 Python 的易用性,又有较强的运行效率。它弥补了 Objective-C 的哪些不足?融合了哪些其他语言的优秀特性?将它和 C# 相比,各有什么优劣?它会对未来的软件开发产生什么影响?作为一个程序员,此刻,一个对世界消费者和消费平台都有着广泛影响力的公司,推出了一个全新的语言,所有人都是0基础,你有什么想法?
关注者
6849
被浏览
546926

111 个回答

2016.07.10 更新

-------------------

现在还处于过渡时期,但趋势很明朗了,Swift 必然会替代 Objective-C,并且比想象中来得快。现在就应该做好准备了。假如之前已经掌握了 Objective-C,切换到 Swift 也不难。Swift 中很多概念在 Objective-C 中已经存在。推荐网站 Swiftify | Objective-C to Swift Converter ,辅助将旧的 Objective-C 代码转成 Swift。


那是不是 Objective-C 就不需要学习呢?并非如此。Swift 还没有很好地解决好跟 C 和 C++ 混编的问题。很多项目底层核心库会采用 C/C++,界面和大部分逻辑采用 Swift 编写,需要 Objective-C 作为粘合层。另外还存留很多库是用 Objective-C 编写的,使用这些库需要一定 Objective-C 知识。


随着时间推移,Swift 在整个 iOS/Mac 工程中占的代码比例会越来越多,而 Objective-C 作为粘合层还是会存在。Objective-C 的语法很独特,就算跟 C++ 写在同一文件,也不会搞混,Objective-C 跟 C++ 混编是很容易的。Swift 调用 C 代码还勉强可以(还不够方便),但直接调用 C++ 没有什么可能。


或者有些人会觉得小小的一个 App,还需要跟 C/C++ 混编?你是小看了 App 了,App 会越做越复杂的。应该当成跟 PC 平台相同的地位看待,PC 平台的软件可以达到什么规模,App 就会达到什么规模。在需要高性能,跨平台的场合,C/C++ 还是绕不开的。


很多人现在还没有学习 Swift, 觉得它没有什么优点,只是一个语言大杂烩。只是等你真正使用 Swift 编写一两个项目,就回不了头。Swift 有些简便快速的写法,在 Objective-C 中是没有办法做到的。并且 Swift 的一些语言特性避免了很多 Objective-C 的坑。使用 Swift 编写的任何功能,使用 Objective-C 也可以做到,但是会麻烦得多。而假如太麻烦的话,明知道是好的,也不会去做。


很多事情,你还没有见识过的时候,会觉得不需要。但等你真正接触过了,就难以忍受再次失去了。我翻看整理 3、4 年前的项目,那时项目还没有采用 ARC。现在看来假如没有 ARC,代码写起来太麻烦了,那时还没有更先进的写法,根本不会有这样的感觉。Swift 比 Objective-C 先进。


现在 Swift 还不稳定,语言、库、相关工具将会快速变动,而这恰好说明它在发展。


很多大公司为求稳,会仍然采用 Objective-C。而个人开发者和小团队,新项目应该直接采用 Swift 编写,旧项目的新模块也应该使用 Swift 编写。这样慢慢将整个语言重心从 Objective-C 切换到 Swift。Swift 的代码更简洁,开发效率更高。原有 Objective-C 项目,已经使用 Objective-C 编写的比较稳定的库,不需要也不建议要用 Swift 重新编写,直接混编,让它慢慢过渡就行了。


大公司倾向于不犯错,求稳。 个人开发者和小团队,求稳一定不能跟大公司竞争的,更应该求好求变。


另外还是会有人说,现在很多公司的项目是规定一定需要使用 Objective-C,那怎么办,我不能选择啊。假如只满足于当前工作,那公司需要什么就去学什么,但从个人发展的角度来说,iOS 开发中,两种语言都需要学习的。其实 iOS 开发中,语言的学习从来就不是难点。


2014.06.06 原回答

----------------

更详细的评论可以再看看这篇文章。从 Objective-C 到 Swift


主要从技术的角度评价 Swift 语言。商业的角度,吸引开发者,共同维护苹果生态圈的繁荣等之类就不说了。


Swift 这门语言还是比较有意思的,很多概念在 Objective-C 中已存在,但打扮过,比原来的模样漂亮。个人感觉,苹果还真的想用它取代 Objective-C 呢。

------------------
Swift 跟 Objective-C 共用同一套的运行时环境

Swift 的类型,可以桥接到 Objective-C 的类型,反之亦然。如 string 对应原来 Objective-C 的NSString, closures 对应 Objective-C 的 block,等等。 Objective-C 积累下来的大量库,代码不用改写,Swift 就直接可以使用。看两个 API 的声明,对比一下

Objective-C

void
dispatch_apply(size_t iterations, dispatch_queue_t queue,
        void (^block)(size_t));

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;

Swift

func dispatch_apply(iterations: UInt, queue: dispatch_queue_t!, block: ((UInt) -> Void)!)

func touchesBegan(touches: NSSet!, withEvent event: UIEvent!)
我怀疑,Swift 中的接口文件,是利用原来 Objective-C,C 中的接口文件自动程序生成的。

同一个工程,可以同时使用 Swift, Objective-C, C, C++ 四种编译语言(额外嵌入的脚本语言另算)

原来的 iOS/Mac 工程,已经可以同时使用 Objective-C, c, C++三种语言。现在支持第四种。Objective-C, C, C++ 三种语言的结合很容易,Objective-C 跟 C 原本就兼容,Objective-C 跟 C++ 混编只要将文件名改成.mm。而 Swift 跟其它语言的结合,需要另外的文件进行桥接,其实也挺方便的。


这里的桥接很容易,Apple自家的各种 C 库移植过来了。比如Core Image/Audio,直接包含

import CoreAudio
import CoreImage

就可以使用了。


现在 Swift 完全可以跟 Objective-C 并存,原来的工程不建议重写,也不用重写。顺其自然,慢慢让它进化就是了。


Swift 写法看起来像脚本语言,但它是真正的编译语言

初学者,看它使用了

let a = 4
var b = "hello"

没有类型定义,就想当然的觉得它是脚本语言,解释执行,这是不对的。上面两行语句是用了类型推导,类似 C++ 里面的 auto。Swift 跟 Objective-C 的运行时环境一样,写的程序跑起来不会比Objective-C 慢。Swift 区分了struct 和 class, 分别使用传值跟传引用。另外类中的函数可以直接调用,而不像 Objective-C 那样需要发送消息,运行速度要比 Objective-C 快一些。


Swift 吸收了很多其它语言的语法,写起来比 Objective-C 简洁得多,不过它的很多概念,跟原来 Objective-C 差不多

编程语言的语法重要,但是语法背后的概念更重要。比如面向对象,常用概念无非是,继承,多态,封装,信息隐藏等。继承又可能分成多重继承,接口继承,实现继承。或者还会有些嵌套类,嵌套函数等等。


当明白语法背后的概念,知道为什么需要有这些东西。之后从一门语言切换到另一门有着相同概念的语言,其实很容易。


而语法会影响表达,理论上每门语言都可以表达任何概念。不过当某种概念在某门语言中,很难表达出来,就会倾向于不这样使用它,这种概念在那门语言的社区就难以被人熟知。


感觉上,Swift 有着 Objective-C, C++, Ruby 的影子。


暂时,我自己最喜欢的3个特性有

  • tuple,终于可以返回多个数值了。一行交换两个值。C++ 里面的 tie+tuple 也可以实现类似功能,不过使用库,显得噪音太多。

  • closure,喜欢它的简写,还有在函数最后一参数,可以写在()外面。这些特性,用来写函数式风格的程序,会很好看。而原来 Objective-C 的block, 还有 C++ 的function, 就太啰嗦了。

  • switch,case 里面的条件匹配。

这些语法,编译最后还是会映射成原来 Objective-C 的运行模型。原来 Objective-C 的概念,引用记数,ARC, 属性,协议,接口,初始化,扩展类,匿名函数等等,继续有效。


有个大块头的东西,是原来 Objective-C 没有的,就是泛型。Swift中 将那种操作写一次,就可以作用多个类型的语法叫做generics(泛型)。


总的说来,Swift 涵盖了现在流行的编程方式,结构化,面向对象,泛型,函数式。


Swift 的新语法,可以很好地支持内部 DSL

有一种编程风格,不太好归类。就是将程序拆分成,描述+解释。解释部分写一次,其它地方使用描述式的语句,而不是命令式的语句。


内部DSL,通常利用主语言的语法特性,创出一套写法,来写一些描述性的语句。这些语句组合起来,就像一门新语言似得。这个比较难理解。举个例子(从ruby那里借过来的),假如计算,几小时之后的秒数。C 语言中,大概会写成

getHourSeconds(3)

而现在 Swift中,只要定义了扩展

extension Int
{
    var hours:Int
    {
        return self * 3600
    }

    var ago:Int
    {
        return -self
    }
}

就可以写成

3.hours
3.hours.ago

分别是 3 小时后的秒数,3 小时前的秒数。


同理,也可以写成

10.days
10.days.ago

这种写法,看起来跟原来的命令式写法完全不同。这些程序是描述性的。原来的 Objective-C, 从语法上做不到这样自然。 我估计 Swift 以后会冒出大量这样风格的库。


这种风格,到底好不好,要看情况。比较方便定义内部 DSL 的语言, 我自己知道的有 C++, Ruby, Lisp。现在多了 Swift。


认为所有人都是0基础的,是错误的

有些人学得特别快,因为之前的基础好。语言的语法只是表面,表面的东西总是变动得比较快的。底下的东西重要得多,而看不见。水面一块冰,有些人是冰山露出一角,有些人是无根的浮冰。看起来差不多,其实差别十分之大。


我相信有些人,在两个小时之内就可以使用这门新语言。之前已经掌握 Objective-C 了,切换到 Swift 中其实也容易。


提提那个Playground

苹果前员工 Bret Victor 有个视频 Bret Victor - Inventing on Principle,提到这种可视化编程。当我们每一步操作,都得到实时地反馈,我们的做法会有很多不同,做出的东西也会不同。这个Playground 用来学习Swift 的特性很好用,但还不能跟实际工程结合起来使用。

先说结论(针对Swift 2.2):Swift把几种主流语言的优势糅合得非常好,是我见过的最漂亮最现代化的语言。

“几种语言的优势”指的是:

Objective C的运行时动态支持,和基于编译期引用计数的内存管理模型,
Ruby灵活优雅的语法,
C++的严格编译期检查,C++11编译期类型推导,模版(之所以说模版template,而不是范型generic,是因为Swift的范型实现依靠编译器更多些,而不像Java/C#依赖于运行时支持),
Javascript和Ruby的closure。

糅合的结果就是,写Swift带给你的极致体验是无与伦比的。

你可以轻松地像Javascript一样用closure写函数式编程,实现callback, aync, 以及类似Promise的代码风格;而同时,你又无需忍受Javascript那样稀烂的类型系统(JS连函数参数的个数都不检查)。语法上,Swift closure几乎和Ruby一样漂亮;Javascript写closure很啰嗦,Objective C写block更难看(那个C函数指针风格的block声明我就没搞清楚过,有码农为此专门写了个blog: Fucking Blocks Syntax),C++写closure?... 眼花。

更舒服的是,Swift通过引入nullable的概念,支持在编译期对nil值进行检查。这一举解决了Objective C因为对nil值过于灵活和宽容导致的问题。而通过optional chaining, 原来的灵活性依然保留。

除此之外,Swift还支持与Objective C混编,完美支持iOS/Mac的SDK。所以在老项目中,过渡到Swift的成本是比较低的。个人推荐老项目转向Swift可以从testcase开始写。

题主说Swift是“基于脚本的编程语言”,这个说法不太妥当。Swift是一门非常严格的编译语言,它的编译期类型检查要比Objective C和Java都要严格,更别提那些真正的脚本语言了。当然,Swift可以在Xcode Playground里即时编辑即时显示结果——那是苹果的黑科技,并不意味着Swift是脚本语言。性能上,Swift不输Objective C。

初学者关心好不好学这个问题。在此也给出明确答案:不好学。Swift不是一门初学者入门语言。不要抱着写Swift可以快速上手的浮躁心态入门iOS开发。
为什么?