作為一名 Go 程式設計師,我為啥更喜歡用 Zig?

2023-12-06     51CTO

原標題:作為一名 Go 程式設計師,我為啥更喜歡用 Zig?

作者 | Vladimir Vivien

編譯 | 如煙

Zig 是一種比較新的程式語言,於 2016 年首次推出。Zig 社區將其描述為「一種用於維護穩固的、可優化和可重用軟體的通用程式語言」。

看似一句簡單的描述,卻隱藏著遠大的抱負。Zig被看作是可與C語言一較高下的程式語言。此外,Zig 也是一個編譯器工具鏈,可以作為現有 C 編譯器的替代品。

作為一個使用 Go 的程式設計師,我發現 Zig 及其工具鏈提出的主張很有意思。我在研究 Zig 時,發現這兩種語言(Zig 和 Go)有一些共同之處。接下來,我將詳細介紹作為 Go 程式設計師,我覺得 Zig 有趣的功能。

1、簡單

這兩種語言都採用了簡單的設計理念,執行過程很順暢,大大提高了工作效率。Zig 不支持宏、預處理器或運算符重載。

Go 是一種託管內存語言,並且運行時有特別的方法來處理內存的分配 / 釋放。但 Zig 始終恪守「無隱藏控制流」的口號,沒有自動內存管理,而是提供 API,讓程式設計師通過其標準庫手動管理內存。

2、強類型

作為一種為系統編程而設計的語言,Zig圍繞其類型系統提供了大量以安全性和C ABI兼容性為中心的特性。雖然我無法充分介紹所有內容,但可以提出一些你可能會感興趣的亮點:

  • 有符號/無符號整數(預設大小從 8 位到 128 位)
  • 任意大小的有符號/無符號整數(即i77 位 int)
  • 浮點(從 16 位精度到 128 位精度)
  • 切片和數組(即 []u8{ 『h』, 『i』, 『!』}或[4]i32{ 1, 2, 3, 4 })
  • UTF-8 編碼的字符串文字,存儲為以 null 結尾的位元組數組
  • 具有 C ABI 兼容性的功能豐富的結構類型
  • 具有隱式/顯式序數值的枚舉和對方法的支持
  • 用於存儲多種類型選擇的值的聯合
  • 支持使用向量的並行運算
  • 傳統指針和帶有切片表達式的多項指針

3、處理錯誤

Zig 中的錯誤處理效果非常好。它是 try-catch-exception 語義和 Go 錯誤值之間的交叉。那麼它是如何運行的?

首先,所有 Zig 錯誤都是必須分配和處理的值(否則將導致編譯時錯誤)。Zig 錯誤使用error這個關鍵字聲明為一組值:

使用二進位運算符 !,可以將Zig錯誤值與正常類型的值組合起來,形成可由函數返回的 Union 類型。

例如,下面的函數可以返回類型為 error 或 u32 的值,返回類型為 !u32(或顯示為DigitError!u32):

此外,Zig 用一個非常有意思的結構來處理錯誤。與其他語言中的異常處理類似,Zig 使用 catch 關鍵字將錯誤處理代碼塊附加到函數調用中,如果返回錯誤值,則該函數調用將被執行,如下所示:

Zig 還支持使用關鍵字 try 在調用堆棧中傳播錯誤的機制。例如,addAll 的功能是如果返回或繼續執行其他操作,下面的函數將返回錯誤。

最後,Zig 可以使用 if-else-switch 來更精確地過濾和處理錯誤結果:

4、Zig測試

在 Zig 中,原始碼測試是一流的組成部分,在該語言中擁有自己的test關鍵字。測試的聲明方式與頂級函數類似,使用 test 關鍵字,後跟描述和代碼塊:

與go test一樣,工具鏈附帶了zig test命令,用於在原始碼中執行測試:

5、Zig運行

與 go run 類似,Zig 提供了一個更便捷的 zig run 命令,結合了編譯和運行 Zig 原始碼的步驟:

6、延遲

與Go類似,Zig使用 defer 來簡化資源管理,以便在當前執行的範圍塊結束時執行清理操作,例如釋放資源。

7、Comptime

comptime是該語言中另一個有趣的概念,在大多數其他語言中都沒有。Zig 沒有單獨的元語言或宏系統。但Zig 提供了一種巧妙的解決方案,使用comptime(或編譯時)的概念將其原始碼的可編程性擴展到編譯階段。

通過comptime,Zig 可以在編譯時實現多種功能:

  • 在編譯時解析的變量和表達式
  • 基於編譯時值運行的函數
  • comptime 編譯期間選擇性執行的代碼塊
  • 編譯時執行的元編程

8、通用性

當然,Zig 編譯時可編程性帶來結果是泛型類型和數據結構的實現。在 Zig 中,comptime 提供對可作為常規數據值存儲和傳遞的類型值的訪問。

這使得創建採用類型參數的函數成為可能,如下所示:

由於 comptime 類型值被視為任何類型,因此 Zig 允許使用它們構建通用數據結構。例如,MakeList 使用 comptime 類型信息返回在編譯時構建的結構:

9、Zig可作為C(交叉)編譯器

Zig 工具鏈具有全功能 C 編譯器,這意味著你可以使用 Zig 來替代當前的 C 編譯器工具鏈。給出以下 hello.c 原始碼文件:

Zig 可以使用以下命令將原始碼編譯為可執行二進位文件:

10、Zig 和 C 交叉編譯

Zig 可以輕鬆交叉編譯代碼(無論是 C 還是 Zig),並且彙集了所有必要的工具和庫,以確保你可以針對其支持的任何架構。

例如,Zig 可以將之前的 C 原始碼交叉編譯為針對 linux 的靜態二進位文件(使用 musl):

11、Zig 和 CGo 交叉編譯

事實證明,Zig 的C交叉編譯支持對於交叉編譯支持Go的Go原始碼非常有用。例如,在 add.c 中添加以下 C 函數:

我們用Go來調用它:

假設在 MacOS 構建代碼,我們可以通過命令 zig cc 來使用 Zig 的 C 編譯器,將 C 代碼交叉編譯為連結到 Go 對象文件的目標文件,從而為在 x86 架構上運行的 Linux 構建靜態二進位文件:

要實現此功能,你只需在工作站上安裝 Zig 工具鏈,無需其他輔助工具。

雖然這看起來沒什麼大不了的,但請記住,交叉編譯支持 CGo 的靜態二進位文件會更複雜(在不使用 Zig 的情況下)。通常需要幾個步驟來準備構建環境,其中包含交叉編譯目標平台所需的軟體包(請參閱此處)。

結論

Zig 夠簡單、夠強大、夠安全又兼備 C 兼容性,備受開發人員青睞 。無論你是在為新項目尋找語言,還是只是想擴展編程能力,Zig 都是值得探索的很棒的選擇。

文章來源: https://twgreatdaily.com/zh-sg/b2c0613d4b19dcad927a09d4fb2c0e59.html