第一次開啟 Objective-C 程式碼時,最先映入眼簾的就是某個特徵。
那就是到處出現的 @(at 符號)。
@interface、@property,甚至連字串都會寫成 @“Hello”。第一次看到時,可能會想:「這不是打錯字吧?」
不過,這個 @ 有非常明確的原因。
Objective-C 的 @ 是用來告訴編譯器:「從這裡開始不是純 C,而是 Objective-C 的擴充語法。」
今天就來輕鬆說明,為什麼這個 @ 會同樣出現在 @interface、@property 和 @“字串” 前面。
Objective-C 的 @ 到底是什麼?
先從重點開始說。
@ 是用來向編譯器標示「這是 Objective-C 專有語法」的特殊符號。
要理解這一點,必須先了解 Objective-C 的起源。
Objective-C 並不是一種完全全新的語言,而是在 C 語言上加入物件導向功能的語言。
也就是完整包含 C 語言,同時額外加入類別和訊息等功能的架構。
但這裡會產生一個問題。
從編譯器的角度來看,必須區分哪些是原本的 C 語法,哪些是後來新增的 Objective-C 語法。
而負責畫出這條界線的標記,就是 @。
為什麼偏偏是 @(at 符號)?
既有星號(*)和井字號(#),為什麼特別選擇 @ 呢?
答案意外地實用。
因為在 C 語言的標準語法中,@ 符號完全沒有被使用。
一起回想一下 C 語言會使用的字元。
- 變數・函式名稱:英文字母、數字、底線(_)
- 運算子:+、-、*、/、=、& 等
- 前置處理器:#(例如:#include)
這份清單裡完全沒有 @。
所以 Objective-C 的設計者採用了 @。因為它是不會與既有 C 程式碼衝突的安全符號。
如果不用 @,而是直接把 interface 這個單字當成關鍵字,那麼既有 C 程式碼中使用 interface 作為變數名稱的部分就會全部失效。
在前面加上 @,就能從根本上避免這種衝突。
簡單來說,@ 就像是收納 Objective-C 專用語法的另一個抽屜把手。
@interface・@property・@“字串” 為什麼全部都是 @
現在進入重點。一起看看這三個看似性質不同的項目,為什麼都以相同的 @ 開頭。
結論是,三者都是「C 沒有、只有 Objective-C 才有的功能」。
我們逐一來看。
@interface — 用來開啟類別骨架(宣告)的指示詞。由於 C 根本沒有類別的概念,因此必須用 @ 標示。配對的 @implementation 和 @end 也是同樣的原因。
@property — 自動建立物件屬性的功能。這同樣是純 C 沒有的語法,因此會加上 @。
@“字串” — 這是最有趣的例子。只有引號的「Hello」和 @“Hello” 是完全不同的東西。
用表格比較一下。
| 分類 | “Hello” | @“Hello” |
|---|---|---|
| 本質 | C 風格字元陣列 | NSString 物件 |
| 所屬 | 原本的 C 語法 | Objective-C 擴充 |
| 功能 | 單純的字元排列 | 可使用 length 等方法 |
只要在引號前加上一個 @,單純的文字片段就會變成「物件」。
所以才需要 @。這就像是在下指令:「請把這個字串建立成 NSString 物件,而不是普通的 C 字串。」
總結如下。
無論是 @interface、@property,還是 @“字串”,都是「C 沒有、只有 Objective-C 才有的功能」,所以都使用相同的 @ 標記。
用程式碼一眼看懂
只用文字說明可能有點抽象,因此準備了一個簡短的例子。
下面是簡單的類別宣告。請觀察 @ 如何包住 Objective-C 語法。
@interface Person : NSObject // 類別宣告開始 (CC 沒有的語法)
@property NSString *name; // 自動產生屬性
@end // 宣告結束
NSString *greeting = @"你好"; // 引號前 @ → NSString 物件
可以看到,以 @ 開頭的行全部都是 Objective-C 新增的功能。
相反地,沒有 @ 的部分則是從 C 語言原封不動沿用的語法。
只要看有沒有 @,就能立刻分辨:「啊,這是 Objective-C 擴充。」
常見問題(Q&A)
Q. @ 和前置處理器的 # 一樣嗎?
不是。#include 中的 # 是在編譯前處理的前置處理器指示詞;@ 則是由編譯器直接解析的 Objective-C 編譯器指示詞(directive),兩者的作用不同。
Q. @ 的種類除了這些之外還有很多嗎?
有,而且不少。例如 @protocol、@selector、@try/@catch、@autoreleasepool 等。在較新的語法中,還能用 @[] 陣列、@{} 字典,甚至 @42 這類數值物件,都能透過 @ 簡單建立。
Q. Swift 裡也有 @,對吧?
沒錯。不過意義稍微不同。Swift 的 @ 主要用於標示屬性(attribute),例如 @State 和 @IBOutlet。根源相似,但用途需要分開理解。
程式碼中到處出現的 @ 可能讓人感到陌生,但了解它是「區分 C 與 Objective-C 的界線」後,反而會覺得親切。
只要跟著 @,就能清楚看出物件導向語法從哪裡開始。閱讀 Objective-C 程式碼時記住這個觀點,會輕鬆許多。祝你今天也享受寫程式的樂趣!

