Go語言AST嘗試

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

Go語言有很多工具, goimports用於package的自動匯入或者刪除, golint用於檢查源碼中不符合Go coding style的地方, 比如全名,注釋等. 還有其它工具如gorename, guru等工具. 作為工具它們都是使用go語言(查看)開發的, 這些工具都有一個共同點就是: 讀取原始碼, 分析原始碼, 修改或產生新代碼.

 

簡述

很多程式設計語言/庫/架構等都能產生代碼, 比如使用rails, 可以輕鬆地new一個project出來, 產生項目基本代碼, 我們稱其為boilerplate, 或者template, 這已經習以為常了. 像ruby的動態語言通常能在運行時產生代碼, 我們稱之為meta programming(元編程), 比如rails的resources可以產生restful的router出來.因為是運行時動態產生, 因此可能會遇到exception, 以及效能方面有所損失.

像elixir這種程式設計語言的macro則比ruby的元編程方面向"前"一步, 它在編譯期產生代碼, 而不在運行時產生, 好處是可以產生大量的代碼而對效能幾乎沒有太大影響. 像phoenix架構的router查看部分, 則通過macro產生大量的函數, 利用BEAM的pattern matching機制高效路由.elixir的macro是寫在原始碼裡的, 而Go則可以分離.

Go語言可以通過reflect包同樣做到ruby的運行時產生代碼(比如建立對象), 但更強大的一點是, 它通過讀取源碼, 再修改源碼, 產生新的代碼.我們可以將這個過程單獨寫作一個工具, 這個工具可以適用於不同的項目.

 

例子

stringer

package game//go:generate stringer -type=GameStatus// 注意//與go:generate字元之間不能有空格// GameStatus 表示比賽的狀態type GameStatus intconst (Unvalid GameStatus = iotaValidFailedValidRegisterStartRunningEnd)

運行 go generate 會產生gamestatus_stirng.go檔案, 並且實現了Stringer介面.

同樣的例子在gRPC中也出現過code, 產生的string.正如Rob Pike所說:

let the mechine do the work.source

 

gen_columns

很多項目在使用資料庫時, 通過tag指定資料庫裡的欄位名字, 在寫SQL時, 又只能通過字串來表示欄位名, 因此如果某一個欄位名修改時, 則意味著涉及到此欄位的SQL都面臨著修改, 而我們希望只需要修改一個地方.

有一個結構作為資料庫表結構如下:

type User struct {    ID int `json:"id" bson:"id"`    Name string `json:"name" bson:"name"`}

當使用這個model裡的欄位進行sql查詢時, 通常使用:

map[string]interface{}{    "id":123456,}

作為查詢條件, 如果當欄位名更改時, 不得不修改這個map裡的key值
如果能夠自動產生一個結構體, 用於表示這些column name值, 那麼只需修改一處:

map[string]interface{}{    UserColumns.ID: 123456}

 

使用方法

gen_columns -tag="bson" -path="./models/user.go"

會產生一個獨立的檔案, 裡面的內容為:

package modelstype _UserColumn struct {ID   stringName string}var UserColumns _UserColumnfunc init() {UserColumns.ID = "id"UserColumns.Name = "name"}

 

總結
gen_columns是自己在項目中遇到問題所給出的解決辦法, 第一版本是通過reflect做的, 總共需要好幾個步驟; 使用ast做就只需在編譯時間多加一個go generate, 而這命令基本上可以整合在build的指令碼裡, 因此不需要再額外擔心代碼產生的問題.
讓我們用Go創造更多產生代碼的工具吧.

  

其它例子 

  • impl 指定一個介面, 產生介面所需方法
  • goa 一套用於寫web service的DSL

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.