我最近一直在探索 Go 的 UTF-8 支持,並且很好奇它在程式碼中處理非拉丁腳本的效果如何。
使用 UTF-8
Go 原始檔預設採用 UTF-8 編碼。這意味著理論上您可以在變數名稱、函數名稱等中使用 Unicode 字元。
例如,在官方的 Go Playground 樣板程式碼中,你可能會遇到這樣的程式碼:
package main import "fmt" func main() { 消息 := "Hello, World!" fmt.Println(消息) }
這裡的「訊息」是中文「訊息」的意思。由於其 Unicode 支持,Go 可以毫無問題地處理這個問題。這種功能是 Go 在中國和日本等國家流行的原因之一——開發人員可以使用對自己語言有意義的識別碼來編寫程式碼。你可能不會相信,但用母語編寫程式碼在中國非常受歡迎,我喜歡它。
嘗試使用泰米爾語識別碼
當然,我想用我的母語泰米爾語試試看。
這是我寫的一個簡單範例:
package main import "fmt" func main() { எண்ணிக்கை := 42 // "எண்ணிக்கை" means "number" fmt.Println("Value:", எண்ணிக்கை) }
乍一看,這似乎很簡單,可以運行而不會出現任何錯誤。
但是,當我嘗試編譯程式碼時,我遇到了錯誤
./prog.go:6:11: invalid character U+0BCD '்' in identifier ./prog.go:6:17: invalid character U+0BBF 'ி' in identifier ./prog.go:6:23: invalid character U+0BCD '்' in identifier ./prog.go:6:29: invalid character U+0BC8 'ை' in identifier ./prog.go:7:33: invalid character U+0BCD '்' in identifier ./prog.go:7:39: invalid character U+0BBF 'ி' in identifier ./prog.go:7:45: invalid character U+0BCD '்' in identifier ./prog.go:7:51: invalid character U+0BC8 'ை' in identifier
了解泰米爾語組合標記的問題
要了解正在發生的事情,有必要了解一些泰米爾語腳本的工作原理。
泰米爾語是一種abugida——一種將每個輔音-元音序列寫成一個單元的書寫系統。在 Unicode 中,這通常涉及將基本輔音字元與表示元音或其他修飾符的一個或多個組合標記組合起來。
例如:
泰米爾語字母க (U 0B95) 代表子音「ka」
要表示“ki”,您可以將 க 與元音符號 ி (U 0BBF) 組合起來,得到 கி。
元音符號 ி 是一個組合標記,在 Unicode 中被明確歸類為「非空格標記」。
這就是問題出現的地方。
Go 的語言規範允許在識別符中使用 Unicode 字母,但排除組合標記。具體來說,識別碼可以包含分類為「字母」的字元(類別 Lu、Ll、Lt、Lm、Lo 或 Nl)和數字,但不能包含組合標記(類別 Mn、Mc、Me)。
泰米爾語組合標記範例
讓我們看看泰米爾語字符是如何形成的:
獨立輔音:க (U 0B95) - Go 識別碼中允許使用。
子音元音符號:கா (U 0B95 U 0BBE) - 不允許,因為ா (U 0BBE) 是組合標記 (Mc)。
輔音元音符號:கி (U 0B95 U 0BBF) - 不允許,因為ி (U 0BBF) 是組合標記 (Mn)。
子音元音符號:கூ (U 0B95 U 0BC2) - 不允許,因為ூ (U 0BC2) 是組合標記 (Mc)。
標識符எண்ணிக்கை(「數字」)中,字元包含組合標記:
எ (U 0B8E) - 信,允許。
ண் (U 0BA3 U 0BCD) - 由ண (U 0BA3) 和 virama ் (U 0BCD) 組成,組合標記 (Mn)。
ண (U 0BA3) - 信,允許。
ிக்கை - 包含組合標記,如 ி (U 0BBF) 和 ை (U 0BC8)。
由於 Go 標識符中不允許使用這些組合標記,因此編譯器在遇到它們時會拋出錯誤。
為什麼漢字可以用而泰米爾語不行
漢字在 Unicode 中通常被歸類為「字母、其他」(Lo) 類別。它們是獨立的符號,不需要組合標記來形成完整的字元。這就是為什麼像訊息這樣的標識符在 Go 中完美運作的原因。
實際意義
無法在識別符中使用組合標記對於泰米爾語等腳本具有重大影響:
表達能力有限:如果不組合標記,幾乎不可能用泰米爾語寫有意義的識別字。
教育障礙:使用本機腳本可以使學習編碼變得更容易,但這些限制阻礙了這種可能性,特別是對於遵循基於 abugida 的書寫系統的語言。
包容性挑戰:雖然 Go 的目標是透過 UTF-8 支援實現包容性,但組合標記的限制排除了許多依賴它們的語言。
Go 的 UTF-8 支援是朝著使程式設計更具包容性邁出的一大步。然而,在標識符中排除組合標記對泰米爾語、印地語和阿拉伯語等語言造成了障礙,在這些語言中,組合標記是腳本的組成部分。
作為一名來自泰米爾納德邦、主要從事 Go 工作的開發人員,這個發現既令人興奮又有點令人失望。它強調了程式語言真正國際化的複雜性。
絕對!與東亞地區不同,那裡不遵循基於“abugida”的書寫系統。
而且,顯然,Go 的創建者一開始就不會打算將 UTF-8 合規性用於「本地語言編碼」。原因更多是為了提供更好的 ASCII 處理、與現代 Web 標準保持一致、一致的字串處理以及邁向互通性的一步。
這次嘗試只是我的好奇心,想了解我們能在 Go 中實現 UTF-8 合規性到什麼程度。作為一個致力於用 Go 建立可擴展的分散式金融科技系統的人,我發現了解這些細微差別至關重要。
就是這樣。感謝您的閱讀。
快樂編碼:)願程式碼與你同在。
以上是Go 的 UTF 支援:一個有趣的限制的詳細內容。更多資訊請關注PHP中文網其他相關文章!