loading请求处理中...
x
当前位置: 首页 > 行业资讯 > 文章详情

从Objective-C到Swift

发布时间:阅读次数:
  • Objective-C因为需要兼容C,所以限制了它的改进。而Swift没有历史包袱,可以自由采用最新的语言设计研究成果。
  • 设计者的个人品位,Chris Lattner不习惯Objective-C的语法,就去设计了一个新的。当然,这是玩笑话,不要太当真。
  • Swift虽然是新语言,却融合了Objective-C的很多特性。读Swift的文档会发现,Objective-C与Swift的联系十分密切。Objective-C使用的很多底层技术,被应用到Swift中。

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

    我们编写程序,让程序运行起来,被机器执行的代码并非全部是由我们自己来编写的。需要同时运行很多预先写好的支持性的代码,才能让我们自己的代码运行起来。程序并非单独存在的,运行时处在一定的环境当中。我总联想到很多小蚂蚁在泥土上面爬,而我自己写的程序只是其中的一只。

    Swift跟Objective-C编译出的程序代码运行在同一套运行环境上面。Swift的类型可以桥接到Objective-C的类型,反之亦然。Swift编写的代码可以调用Objective-C编写的代码,反之也一样。

    Objective-C之前积累下来的大量类库,实现不用改写Swift就可以直接调用。

    同一个工程,可以同时使用Swift和Objective-C

    Objective-C在一端,Swift在另一端,两端经中间文件进行桥接。桥接文件包含Objective-C的头文件,编译时自动转成Swift可以识别的形式。Swift就可以使用Objective-C的类和它的函数。

    在Swift的类中,加上@objc(类名)的字样,Objective-C也可以使用Swift编写的类。但Swift跟C++的相互调用,需要Objective-C来封装。

    总的来说,共同使用Swift和Objective-C/C++还算方便,但已不能将几种语言的代码,混写在同一文件。大概是因为Swfit的语法不像Objective-C那样独特,混写难以将Swift的代码识别出来。

    Swift骨子里大多与Objective-C一样

    Objective-C出现过的绝大多数概念,比如引用记数、ARC、属性、协议、接口、初始化、扩展类、命名参数、匿名函数等,在Swift中继续有效(可能只是换了个术语)。我自己将Swift看成是Objective-C的一块大大的语法糖,其他人可能有不同感受。

    Swift大多数概念与Objective-C一样,也有些概念在Objective-C找不到对应,比如泛型。Swift中将那种操作写一次就可以作用多个类型的语法叫做Generics(泛型)。

    编程语言和语法

    新语言出来时,总会有种声音认为语言只是工具,他们会觉得重要的是思想,而看轻工具的作用。认为编程语言是工具本身并没有大错,但语言并非普通的工具,而是思维工具,不能忽视语言对思维的影响。编程语言就如同数学符号,数学符号也是种思维工具,好的数学符号会帮助使用者思考,更奇妙的是似乎符号本身也会思考。用0~9这些阿拉伯数字进行计算时会感到一切都很自然,似乎数字本身在计算,而不是人在做计算。

    尽管编程语言的语法很重要,但语法背后的概念更重要。当明白语法背后的概念后,从一门语言切换到另一门有着相同概念的语言会很容易。但语法会影响表达,理论上每门语言都可以表达任何概念。不过当某种概念在某门语言中很难表达出来时,我们就会倾向于不使用它,这种概念在那门语言的社区就难以被人熟知。

    编程语言用来表达思路,表达起来是否自然是很重要的。最理想的是不多不少、刚刚好,写起来自然,读起来更需要自然。并非功能越多的语言越好,而是应该越能帮助思考,越容易表达思路的语言越好。

    Swift背后的概念大多跟Objective-C差不多。但Swift吸收了很多其他语言的语法,同一个概念,写起来比Objective-C简洁得多、自然得多。从表达的角度来说,Swift比Objective-C优秀。

    Swift的语法

    苹果出了本很不错的语法教程来详细描述Swift的语法。在这里,我们只挑一些有意思的点来讨论。

    简洁

    Swift的语法给人第一感觉就是简洁干净。如果省略掉也不引起歧义,那符号基本上可以被省略。

    我们来看下面这个例子:


    Swift写起来,有点像脚本语言。这里没有出现类型定义,有人觉得它就是脚本语言,是解释执行的。而实际上Swift是真正的编译语言,通过类型推导,变量的类型可以确定下来。既然省略掉类型也不引起歧义,也就可以省略了。上面的例子中,传统的句末分号可以省略;循环中的()也可以省略;循环1是C语言中的传统写法;i作为计数变量;循环2是循环1的等价写法,因为根本不用关心计数变量,因此可以直接写成“_”。

    不再兼容C语言,修正Objective-C中容易出错的地方

    例子1

    在C/Objective-C中,if、while、for之后的判断式并不需要一定传入布尔类型。也可以传入整型、指针等类型,只要非0就为真,并且赋值是有副作用的。比如:

    上面代码返回a的数值,这样就有可能出现将判断:


    错写成:


    为避免这个问题,有种变通写法:


    这种写法被称为Yoda表达式,因为《星球大战》中的Yoda大师喜欢使用这样奇特的倒装句子。

    Swift强制要求if、while、for后面判断式子一定需要传入布尔类型,并且赋值没有副作用。因此写成以下这种判断就会编译错误。Yoda表达式这种变通写法再也没有必要。


    例子2

    还是拿判断来说。在C/Objective-C中,if、while、for之后的语句假如只有一行,是可以省略掉大括号的。比如:


    当后面的人修改代码,或多人修改同一代码再合并时,可能会在if后面直接插入一行,这样就一定会goto fail了:


    在Swift中,强制要求if、while、for之后一定需要写大括号,不管是不是只有一行。这样就避免了上述问题。

    不难看出,Swift的语法设计使一些C/Objective-C常见错误不可能再出现。

    常用类型集成到语言里面,而非以库的形式提供

    有几种类型,几乎每个项目中都使用到了,分别是:整数、浮点数、布尔型、空值;字符串;数组、字典。

    对这些类型的支持,每个语言都有所不同。有些老旧的语言不支持浮点;有些语言中,布尔和空值是整数的一种;有些语言中,整数和浮点数合并成一类,统称为Number;有些语言中,并没有字符串、字典、数组;有些语言中,字典和数组归成一类。

    语言不提供的类型多数以库的形式提供。比如在C++中,语言内部并没有提供字符串、字典、数组,但这些类型却出现在了标准的库中。使用库的形式来提供常用类型,优点是减少语言自身的复杂度,另外库可以自由替换。而采用语言直接支持的方式,使用起来会很简洁流畅。Swift中的常用类型集成到了语言内部。 数组写成:


    字典写成:


    这种写法在原来的Objective-C中就已出现,现在融入到了Swift中。

    此外,Swift还支持另外两种类型:option和tuple。option表示有值或根本无值;tuple则表示多个值,它可以从函数中返回多个值,或一行代码交换两个值。

    在C++中,这两种类型也采用库的方式来提供。std::tie与std::tuple结合,可以达到返回多重值的效果,但显得语法噪音多、不够方便,所以也比较少用。

    支持多种编程泛式

    将Swift分拆开,可大致分成以下部分:基本类型、控制流、函数定义和调用、函数式编程、面向对象、泛型。

    实际上,Swift的内容包含很多,也可以说很复杂,并非表面上看起来那样简单。Swift从语法上直接支持现代流行的编程泛式,包括:结构化编程、函数式编程、面向对象、泛型。每个部分Swift都有些闪光点,在此无法一一述说。

    值得一提的是,我特别喜欢它的函数式编程部分。接下来我们直接拿文档的一个排序例子,看看它是怎么简化编程的。

    最开始版本,传递函数


    使用闭包


    推导出参数类型,参数类型省略


    推导出返回类型,return省略


    省略掉闭包里面变量


    假如闭包是函数的最后一个类型,可以将{}提到外面


    使用操作符函数,最后版本


    很好地支持内部DSL

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

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


    而现在Swift中定义了扩展:


    因此可以写成(分别是3小时后的秒数和3小时前的秒数):


    同理,也可以写成:


    这种写法看起来跟原来的命令式写法完全不同。这些语句是描述性的,而原来的Objective-C做不到这一点。估计Swift以后会冒出大量这样风格的库。至于这种风格到底好不好,要看具体情况。据我所知,比较方便定义内部DSL的语言,原来有C++、Ruby、Lisp,而现在又多了Swift。

    Swift的语法还有很多有意思的地方。比如属性的中get、set写法;switch case中的模式匹配;泛型中的类型约束等。这里不一一细说了。

    Swift的争议

    下面列出一些Swift争议性较大的地方:

    • 东抄西抄一些语法、大杂烩,没有自己的原创;
    • 没有一些private、protected之类的权限控制;
    • 没有采用GC(垃圾回收),却采用ARC(自动引用计数);
    • 没有异常处理;
    • 是否可以跳过Objective-C,直接学习Swift。

    对这些争论,我们很难作出客观的评价,更不可能武断地下结论。我感觉Swift这门语言还是比较有意思的(有些人写程序只是单纯为了好玩)。

    这里特别提一下异常处理。以往我一直觉得异常处理是很好的特性,现在觉得异处理常并非一定是好的。异常处理的问题在于发生异常的地方与处理异常的地方分离开来,真正处理时难以收集到足够的信息。异常也容易滥用,很多初学者的Java代码,只抛出异常而不处理,或干脆在最外层接收所有异常,再打印出异常信息。这样也就失去了异常处理的意义。Objective-C中也有异常处理的功能,但实际上几乎没有人使用。对于Swift,采用多返回值加上option的方式来处理错误可能会更好。

    可视化编程

    WWDC发布会上演示了Swift的Playground功能。敲入代码,立即有反馈。当我们每一步操作都得到实时的反馈时,我们的做法会有很多不同,做出的东西也会有不同。可视化编程放到最后,并非是表示它不重要,而是它实在太重要了,只是目前有能力评说的人还不多。关于这部分内容, Bret Victor有几个演讲视频和文章,建议大家看看。

    Swift还有很多主题,只能靠大家自己研究了。最后拿出本次WWDC的Slogan与大家分享:Write the code,Change the world。

        一品威客网,新型设计开发 托付式服务平台
    • 发布一个任务,让千万威客为您服务!
    立即发布一个需求

    创意交易

    为什么选择一品威客

    千万专业威客商铺
    威客实名认证,雇主放心交易
    担保交易,满意后付款
    赏金托管一品,安全全程保障
    无风险,免费发布
    所有类型任务,雇主免费发布
    无风险,全额退款
    零交稿零投标,任务全额退款

    快速发布一个任务

    让一品千万人才为您分忧解难!
    • 需求标题
    • 需求分类
    • 手机号码
    • 手机验证码