Swift 與 Objective-C

Swift 字串長度:實測韓文、表情符號與位元組

比較Character、Unicode scalar、UTF-16與UTF-8長度,驗證等價韓文字典鍵,以及不切斷家庭表情符號的前綴截取。

閱讀 3 分鐘
Swift 字串長度:實測韓文、表情符號與位元組 封面圖

實作字串限制前,先確定計數單位。Swift的count計算Character,也就是擴展字素叢集;傳輸大小通常以位元組計算。畫面相同的字元,內部大小仍可能不同。

原理與設計判斷

實驗的韓文音節可用一個預組合純量或三個組合字母純量表示。Swift String考慮正規等價性,字典查詢也能使用等價鍵。家庭表情符號則示範多個純量形成一個Character。其他語言計算不同單位,本身不代表錯誤。 第一手資料

重現程式碼

用Unicode escape固定精確輸入,比較韓文兩種形式的Character、純量及UTF-8數量。測量家庭表情符號的UTF-16與UTF-8長度,將它放在A與B之間,再用prefix與String.Index操作。空字串另外測試。

這個獨立範例已於 2026-10-23 使用 Apple Swift 6.4,以 Swift 6 語言模式在 arm64 macOS 目標環境執行。不需要網路或額外套件。

下載完整 Swift 檔案

請在下載檔案的資料夾執行。檢查不符時,precondition 會中止程式。請勿使用 -Ounchecked,因為它會移除這些檢查。

swift -swift-version 6 swift-string-grapheme-cluster-indexing.swift
let composed = "\u{D55C}"
let decomposed = "\u{1112}\u{1161}\u{11AB}"
precondition(composed == decomposed)
precondition(composed.count == 1 && decomposed.count == 1)
precondition(composed.utf8.count == 3 && decomposed.utf8.count == 9)
precondition(decomposed.unicodeScalars.count == 3)
let lookup = [composed: 42]
precondition(lookup[decomposed] == 42)

let family = "\u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F467}\u{200D}\u{1F466}"
precondition(family.count == 1 && family.unicodeScalars.count == 7)
precondition(family.utf16.count == 11 && family.utf8.count == 25)
let text = "A" + family + "B"
precondition(text.count == 3 && String(text.prefix(2)) == "A" + family)
let second = text.index(after: text.startIndex)
precondition(String(text[second]) == family)
let empty = ""
precondition(empty.first == nil && empty.prefix(2).isEmpty)
print("hangul=characters:1,scalars:1/3,utf8:3/9 equal:true dictionary:42")
print("family=characters:1,scalars:7,utf16:11,utf8:25 prefix=2 empty=safe")

執行結果與解讀

hangul=characters:1,scalars:1/3,utf8:3/9 equal:true dictionary:42
family=characters:1,scalars:7,utf16:11,utf8:25 prefix=2 empty=safe

兩種韓文形式都是一個Character,但UTF-8分別為3與9位元組,分解形式有三個純量。等價字典鍵可查得42。家庭表情符號有一個Character、七個純量、十一個UTF-16單位、二十五個UTF-8位元組。prefix(2)不會切斷表情符號。

適用範圍與限制

Character不保證完全符合所有語言中人對一個字的理解,仍需考慮分割規則與Unicode版本。不能把韓文或表情符號一律算成每字三位元組。Swift Dictionary也不總是需要明確NFC正規化,但外部系統的比較與編碼契約須另行確認。

接下來要確認的事

先讓伺服器與用戶端對字數或UTF-8位元組限制達成共識。預覽可用prefix等Character API;頻繁隨機存取則比較陣列轉換成本與記憶體。缺值與空字串的區別可接著看Optional實驗。

延伸實驗

來源與驗證