漫谈Objective-C在语法上的进化

Objective-C 2.0从2006年正式发布至今已经有8年了。Apple在此期间也不断地为其注入新的语法特性,比如Blocks、NSNumber literal、NSNumber literal、NSArray literal、NSDictionary literal、Object subscripting等等。然而,其核心语法变化不大。

本人从2009年夏季开始接触Objective-C,一开始总是不习惯其[object   message]这种语法形式,不过随着Xcode自身智能感知的不断加强,编辑也逐步方便,所以也渐渐地习惯了,呵呵~现在用下来,感觉Objective-C在面向对象编程方面有其独到之处,而且灵活性相当大,编译器负担也很小,增加的仅仅是运行时库。不过相对于Java这种需要虚拟机的运行时来说要小得多。因此,它是对C++与Java的折衷。C++太过依赖编译器,Java的运行时太过庞杂,而且这两种编程语言对于类型的限制太过重,导致原本一些本应该十分灵活强大的语法特性也受到很多制约。所以,本人也时常跟朋友、同事之间开玩笑地说,“用C++来做项目,总是先考虑其各种语法糖以及各种坑,而往往不能开门见山地进行软件设计”。而Java新增的很多语法也是比较鸡肋,比如泛型就是其中之一,还有Java 8所引入的Lambda表达式。这货跟Java 1.4所引入的匿名类对象没太大不同,反而是Method Reference更有用些,呼呼~

当然,Objective-C也不能说完全没有缺陷,下面我就谈谈目前Objective-C比较令人不快的特性以及其改进建议。

1、消息发送机制

一开始,Brad Cox引入[object  message]的机制确实不错,这个对已有的C语言语法没有任何冲突,因此Objective-C至今对于C/C++的兼容性都能做到100%。不过,这种写法对于编写代码来说有个很大的弊端——当嵌套的方法调用过多时,由于需要往前加[,因此,对于使用不带智能感知的编辑器来说就相当讨厌了。比如:

NSString *str = [[[NSString alloc] initWithFormat:@"%zu", [@"Hello" length]] autorelease];

上述代码嵌套了多层方法调用。但是对于程序员来说,写代码时都是按照线性思维进行的。也就是说,我一开始总是会想到先分配一个NSString对象,然后调用init初始化方法对其初始化,最后想到用autorelease方法来省去后面手工release的麻烦。而用[]机制,那么你每写好一个方法调用就需要回过去加[,这显然十分麻烦~

而本人这里所提供的改进意见是,使用 <| 这个token来表示消息发送机制:

object <| (message)

上述代码可写为:

NSString *str = NSString <| (alloc) <| (initWithFormat:@"%d", 100) <| (autorelease);

整个调用过程就显得更为清晰。为何方法调用需要用()包裹?我们就看上述例子,如果没有括号,那么initWithFormat:@"%d", 100 <| autorelease直接就会导致歧义。由于<|的优先级与C语言中的 . 操作符、-> 操作符一样,都是左结合的。因此,如果这里没有括号,加上逗号优先级是最小的,那么词法解析器就会解析为 100 <| autorelease,显然不是我们所想要的。

这里,(message)是一个整体,括号里不能放其它东西,比如:(a++, alloc)这种就是非法表达式。当然,我们可以这么写:

NSUInteger a = 10;
a = (a++, @"Hello" <| (length));

这样,就相当于先做a++操作,然后把@"Hello"的长度给a。

时间: 2024-12-28 06:35:40

漫谈Objective-C在语法上的进化的相关文章

数据库oracle与mysql在语法上的区别

转自http://blog.csdn.net/huanghm88/article/details/8009048 数据库oracle与mysql在语法上的区别不是很多,但是也有一些.下面是部分参考: 1,oracle没有offet,limit,在mysql中我们用它们来控制显示的行数,最多的是分页了.oracle要分页的话,要换成rownum. 2,oracle建表时,没有auto_increment,所有要想让表的一个字段自增,要自己添加序列,插入时,把序列的值,插入进去. 3,oracle有

辛星浅析PL/pgsql语法(上)

最近在研究postgresql,因此也就对PL/pgsql产生了浓厚的兴趣,因此这里就来稍微的总结一下,首先说一下的是这个PL是Procedure Language的简写,也就是所谓的"过程语言". 下面的很大一部分内容都是引用自pgsql手册,但是也根据自己的理解进行了一些简单的改变. 第一,调用时机 其中PL/pgsql的函数被第一次调用的时候,其函数内的源代码会被解析为二进制指令树,但是对于函数内的表达式还有一些指令,只有在被首次使用的时候,pgsql才会给它制定执行计划,而且这

Java 和C/C++的“语法”上的差异!

额其实认为语言语法之间是没有可比性的! 但是因为额曾经学过C/C++,而今又学Java,有赵本山说的话:“知识都学杂了!”,所以我个人总结一下,望提醒自己! Java 和C/C++的对比: Java中: double 要用%f: 布尔型:boolean: 字符型占两个字节: If , while,for 中进行真假判断时只能使用逻辑表达式,不能用数字. 较长的整数后要加L: 默认所有实数都是double类型的: 安全性高:当高级类型转换为低级类型会报错!例:想要将double转换为float,

吾八哥学Python(三):了解Python基础语法(上)

学习一门开发语言首先当然是要熟悉它的语法了,Python的语法还算是比较简单的,这里从基础的开始了解一下. 标识符1.第一个字符必须是字母表中字母或下划线'_'.2.标识符的其他的部分有字母.数字和下划线组成.3.标识符对大小写敏感. 保留字保留字就是关键字,不能用它们做任何标识符.Python里通过有一个keyword 模块,执行keyword.kwlist可以输出当前版本的所有保留字,如下: ['False', 'None', 'True', 'and', 'as', 'assert', '

PHP与Java语法上的简单对比

最近一朋友准备从java转PHP,帮她写个简单的PHP入门,简单的讲一下java与php的不同. PS. ueditor实在不会用- -,凑合着看吧 PHP Java 文件格式 <% %>或是<%php %>把代码包含在里面 保存为.php文件 直接书写 保存为.java文件 语言类型 即时编译执行 静态编译执行 注释 PHP独有 # 这也是单行注释 与java相同点: // 这是单行注释 /* 这是多行注释块 它横跨了 多行 */ 变量命名 PHP独有 变量以 $ 符号开头,其后

关于在qt(c++语法上)使用中的一些问题

1.在C++语言中,一个派生类可以从一个基类派生,也可以从多个基类派生.从一个基类派生的继承称为单继承:从多个基类派生的继承称为多继承. 派生类的定义格式 单继承的定义格式如下: class <派生类名>:<继承方式><基类名> { <派生类新定义成员> }; <继承方式>常使用如下三种关键字给予表示: public 表示公有基类: private 表示私有基类: protected 表示保护基类: 2.如果所使用的类名是名字空间(namespa

Julia 的 cross product 与 MATLAB 的语法上似不同

MATLAB example 在这里:http://cn.mathworks.com/help/matlab/ref/cross.html#bt9u1o8-2 Julia 0.3.8 按上面示例执行,会得到错误:元素用逗号分开,可得正确结果.

java学习笔记(二)基础语法(上)

Java 作为一门编程语言,与其它语言一样,有字符集,标识符和关键字,变量,常量,语句等编程语言的基本要素. 关键字:abstract抽象的,boolean布尔型,break跳出循环,continue中止本次循环,byte字节型,case,catch,char,class,const,default,do,double,else,extends,assert,final,finally,float ,for,if,implements,import,instandceof,int,interfa

php和其他语言语法上的一些区别

1.php语言标记 在php.ini文件中将short_open_tag设置为on,php将会识别<?     ?>语言标记 2.php语言注释 // # /* */   多行注释 3.可变变量 <?php $var="php"; $php="php100.com"; echo $var;   //输出结果为php echo $$var;  //输出结果为php100.com ?> 4.字符串 <?php $title='php100'