golang 的 embed 的功能真是一個很神奇的功能,它能把靜態資源,直接在編譯的時候,打包到最終的二進位制程式中。
為什麼會設計這麼一個功能呢?我想和 golang 的崇尚簡單的原則有關係吧。它希望的是一個二進位制檔案能走天下,那麼如果你作為一個 web 伺服器,還需要依賴一大堆的靜態檔案,終究不算是一人一天下,所以就提供了這麼一種處理靜態資源的辦法。
golang 一旦提供了這種方式,可能會有哪些應用呢?我這裡腦洞一下:
web 服務內嵌單頁應用
目前的 web 應用很流行單頁應用,基本上就一個 html+一個編譯後的 js 就能搞定,那麼我提供 web 伺服器就直接透過 golang 編寫,embed 方式將 html 和編譯後的 js 內嵌到伺服器中,那麼就能很方便進行部署了。
app服務內嵌單頁應用
同 web 服務一樣,如果我使用 golang 寫的是一個帶有瀏覽器外框的 app 程式,內部使用 html+js進行渲染,那麼豈不是這個服務就可以在手機/桌面端進行執行了?
可執行檔案的版本管理
這下我們可以再倉庫的根目錄建立一個 version.txt, 裡面填寫上你的倉庫的版本號,在專案中使用 embed 引入這個檔案。如果你的專案是一個可執行檔案,就能在執行的時候,直接顯示出版本資訊了。
可執行檔案的git的commit顯示
我們其實很希望知道我的這個可執行檔案是對應 git 的哪個 commit,如果能將 .git 下的檔案中的 commit 號直接 embed 到程式中就好了。
當然.git下的檔案是不能直接 embed 的,但是這裡提供了一種 generate+embed 的方式來實現:
Embedding Git Commit Information in Go Binaries
可執行檔案的 readme
以前一個可執行檔案在輸入 help 的時候,需要顯示一個資訊內容,在 git 專案外也要有個 readme,其實兩者都是對這個專案的幫助。那麼現在,就能使用 embed 將兩個合而為一了。
licence注入
我不確定golang 的二進位制程式是否很容易被反編譯,但是相較於簡單的 licence 發放,將 licence 編譯進入二進位制程式已經是安全不少了。
我們要控制某個程式的發行,那麼就在給使用者編譯二進位制程式的時候,將對應的 licence 以 embed 的形式編譯進入,然後在程式執行的時候,去遠端或者本地使用非對稱解密等方式來驗證這個 licence 的合法性。
提高效能
我們可以將一些中間結果,比如 xxx 預計算模型啥的,以 embed 的形式內嵌進入程式。
程式執行的時候,就能將這些中間結構和預計算模型反序列化出來。
template檔案進行embed
之前使用 golang 的 template 的時候,往往要建立一個很大的 template 的變數,而這個變數往往就是 html 或者 txt。現在就能獨立將這個 html 或者 txt 放在 git 倉庫中,在編譯的時候 embed 進入。部署的時候直接使用了。
這樣看程式碼的時候邏輯很清晰,執行的時候也很便捷。
參考
//go:embed 入門
Go 語言 | 1.16 新增的embed在各流行Web框架中的應用
道理我都懂,但 go embed 究竟該怎麼用?
Go embed 簡明教程
How can I embed hidden file in Go?
Embedding Git Commit Information in Go Binaries