【问题标题】:Why does Objective-C use square brackets for messages?为什么 Objective-C 使用方括号来表示消息?
【发布时间】:2014-05-18 15:49:34
【问题描述】:

我正在读一本关于 Smalltalk (Charmond Liu's Smalltalk, Objects and Design) 的书。他以HomeBudget 对象为例,讲述了消息在 Smalltalk 中是如何工作的,以说明如何发送具有多个参数的单个消息:

HomeBudget spend: 229 on: 'VCR'

Objective-C 使用了 Smalltalk 的许多想法,例如消息传递对象和参数的冒号,但始终将消息发送括在方括号中。同样的调用是:

[homeBudget spend:229 on:@"VCR"];

为什么 Objective-C 使用方括号(而不是像 Smalltalk 那样让消息裸露)?因为它是基于 C 的,所以它是必需的语法吗?这是一个风格的选择吗?它是否为您可以表达的内容提供了更多选择?还有其他原因吗?

【问题讨论】:

  • 从解析的角度来看,我怀疑这与在 C 语法中玩友好有关。
  • @mah 事实上,Objective-C 最初是作为自定义 C 预处理器 + 运行时。预处理器直接喷出 C 代码,这些代码在方法调用站点和类中调用到运行时,基本上是美化的 C 结构(实际上仍然如此)。
  • bbum 怎么说。当您进行嵌套调用时,Smalltalk 语法有点模棱两可也有帮助,因此您通常不得不将方法调用括在括号中,例如((Class foo: 15) bar: 7) 所以出于实际目的,实际上 Smalltalk 也需要括号。
  • 大部分情况下,我怀疑它使构建 Objective-C 预处理器变得容易得多。必须对较少的 C 语法进行解析和仔细分析才能识别“消息”并将其替换为等效的 C 代码。如果没有括号,预处理器会在标签定义方面产生一些歧义。

标签: objective-c syntax smalltalk


【解决方案1】:

我发现an interview with Brad Cox 似乎暗示方括号用于语法:

DD: 方括号是Objective-C 语法的一个独特部分。方括号是怎么来的,这是你做的吗?

BC:是的,就是我。从字面上看,这是对没有被采取的东西的搜索。带了花括号。带了普通括号。这只是搜索不会与 C 使用的东西冲突的大括号。

Tom Love 在 Masterminds of Programming 中也将方括号归功于自己,但他似乎在说这是一种风格选择:

我经常称自己为负责 Objective-C 中方括号的人,因为 Brad 和我进行了长时间的交谈。我们是否有一种始终如一的 C 语法,或者我们是否创建了一种混合语言,我将其描述为“方括号是进入对象领域的齿轮”?我们的观点是,如果你有一种混合语言,你可以构建一组基础类,以便在某些时候大部分工作实际上是在方括号内完成的。这允许对典型的应用程序程序员隐藏很多细节。

方括号表示在 Objective-C 中发送的消息。最初的想法是,一旦你建立了一组类库,那么你将花费大部分时间在方括号内实际操作,所以你实际上是在使用底层对象框架进行面向对象编程它们是用混合语言开发的,它是过程语言和面向对象语言的组合。然后,当您开始构建功能库时,进入程序世界的要求越来越少,您可以留在方括号内。设计一种基本上有两个层次的语言是一个深思熟虑的决定——一旦你建立了足够的能力,你就可以在更高的层次上操作。我实际上认为这是原因之一。如果我们选择了一种非常类似于 C 的语法,我不确定是否有人会再知道该语言的名称,而且它很可能不会在任何地方仍在使用。

【讨论】:

    【解决方案2】:

    Objective-C 是“C”的严格超集,因此所有添加都需要不改变“C”语言。所有“C”程序也是有效的 Objective-C 程序。

    C++ OTHO 确实对“C”语言进行了更改,因此并非所有有效的“C”程序都可以使用 C++ 编译器进行编译,也不是有效的 C++ 程序。

    因此有必要找到“C”中未使用或至少未在冲突上下文中使用的符号。因此在 Objective-C 中大量使用“@”。在其他情况下添加符号以消除“C”的歧义。

    【讨论】:

    • 前面带@的任何东西都是编译器指令,不一定是语言特性。
    • @CodaFi 您是否在这里混淆了预处理器指令(以 # 开头)?术语“语言特性”足够模糊,它肯定可以涵盖属于 ObjC(或 C++,或您所谈论的任何语言)的任何东西
    • 嗯,迂腐。 @-directives 表示编译器需要执行一些分析,而不是简单的预处理器。例如,@autoreleasepool 指令可能扩展为 objc_autoreleasepool[push/pop],@interface 指令通过 iVar 声明确定对象的大小及其在对象文件中的元类信息。 @property 声明会生成具有潜在生命周期的 setter 和 getter。这一切都可以手工完成,只是因为指令我们不这样做。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-02
    相关资源
    最近更新 更多