问题:为什么 Objective-C 的方法调用要用方括号 [obj foo],而不是别的语言常常使用的点 obj.foo ?
答案:
首先要说的是,Objective-C 的历史相当久远,如果你查 wiki 的话,你会发现:Objective-C 和 C++ 这两种语言的发行年份都是 1983 年。在设计之初,二者都是作为 C 语言的面向对象的接班人,希望成为事实上的标准。最后结果大家都知道了,C++ 最终胜利了,而 Objective-C 在之后的几十年中,基本上变成了苹果自己家玩的玩具。不过最终,由于 iPhone 的出现,Objective-C 迎来了第二春,在 TOBIE 语言排行榜上,从 20 名开外一路上升,排名曾经超越过 C++,达到了第三名(下图),但是随着 Swift 的出现,Objective-C 的排名则一路下滑。
Objective-C 在设计之初参考了不少 Smalltalk 的设计,而消息发送则是向 Smalltalk 学来的。Objective-C 当时采用了方括号的形式来表示发送消息,为什么没有选择用点呢?我个人觉得是,当时市面上并没有别的面向对象语言的设计参考,而 Objective-C 「发明」了方括号的形式来给对象发消息,而 C++ 则「发明」了用点的方式来 “发消息”。有人可能会争论说 C++ 的「点」并不是真正的发消息,但是其实二者都是表示「调用对象所属的成员函数」。
另外,有读者评论说使用方括号的形式是为了向下兼容 C 语言,我并不觉得中括号是唯一选择,C++ 不也兼容了 C 语言么?Swift 不也可以调用 C 函数么?
最终,其实是 C++ 的「发明」显得更舒服一些,所以后来的各种语言都借鉴了 C++ 的这种设计,也包括 Objective-C 在内。Objective-C 2.0 版本中,引入了 dot syntax,即:
a = obj.foo 等价于 a = [obj foo]
obj.foo = 1 则等价于 [obj setFoo:1]
Objective-C 其实在设计之中确实是比较特立独行的,除了方括号的函数调用方式外,还包括比较长的,可读性很强的函数命名风格。
我个人并不讨厌 Objective-C 的这种设计,但是从 Swift 语言的设计来看,苹果也开始放弃一些 Objective-C 的特点了,比如就去掉了方括号这种函数调用方式。
所以,回到我们的问题,我个人认为,答案就是:Objective-C 在 1983 年设计的时候,并没有什么有效的效仿对象,于是就发明了一种有特点的函数调用方式,现在看起来,这种方式比点操作符还是略逊一筹。
大多数语言一旦被设计好,就很难被再次修改,应该说 Objective-C 发明在 30 年前,还是非常优秀的,它的面向对象化设计得非常纯粹,比 C++ 要全面得多,也比 C++ 要简单得多。