go-tour源碼閱讀


go-tour是一個web項目,具有很強的可讀性。

下面先看下里面的目錄

appengine:這個包是當你想把go-tour布置到GAE上的時候使用的安裝,我們這里只是使用本地安裝,所以這里的代碼可以不看

solutions:這個文件夾可以忽略,只是對文檔中execise的答案,與go-tour網站無關

talks:這個是作者做的關於go-tour的演講放在這里面,也可以直接忽略

static:這個文件夾是存放靜態資源,js,css,html都是放在這里面

tree:這個文件夾存放程序自動生成一個樹的代碼包。這個是具體的功能才使用到的,與網站無關

wc:測試套件。這個是具體的練習題中才使用的到,與網站無關

pic:對圖片的處理包。這個是具體的練習題中才使用到的,與網站無關

gotour:這個才是真正的go-tour的入口,main包在這里

 

從gotour/local.go看起

直接在全局變量中寫了兩個參數http和html。

http說明是在哪個端口監聽。

html是說明是輸出html頁面還是打開,這個html是沒有用的,估計作者想做這個功能來着,還沒做完。

init函數是將編譯生成的可執行文件存放的臨時文件夾設置好。

進入main函數,有個uniq的chan int,這個是為了給臨時文件做唯一標示的,會不斷增長的。

main中的uniq是一個id生成器,這個方法很常用

 

var ( 
     // a source of numbers, for naming temporary files
     uniq = make(chan int)
)

func main() { 
     flag.Parse()
     // source of unique numbers
     go func() {
          for i := 0; ; i++ {
               uniq <- i
          }
     }()
}

main中首先獲取go-tour的目錄,它是使用build包來獲取,可以學之當做固定模板

// find and serve the go tour files 
p, err := build.Default.Import(basePkg, "", build.FindOnly)
if err != nil {
    log.Fatalf("Couldn't find tour files: %v", err)
}
root := p.Dir

 

 

下面就是使用http包做不同的路由了。

有幾個不同的路由器:

/ ,  /favicon.ico, /static/ , talk/,  kill

 

kill是殺死一個running的命令。這里有個running是為了跑正在運行的程序

run函數很好的演示了如何運行系統命令,並且輸出結果

好了,這里的main看完了,當你實際運行的時候你會發現,程序中對代碼的編譯實際上是使用/compile和/fmt兩種。這兩種訪問路徑是在goplay.go和fmt.go中定義的

 

先看goplay.go

直接在init()中寫上了HandleFunc,這樣也能更醒目地告訴所有人,這里的包是為了編譯使用

Compile函數中的具體實現步驟是用compile函數(local.go中)來實現的,后面就是json編碼后輸出。

下面看main中的compile,main中有維持一個running結構,這里值得注意的是它使用的初始化直接在struct定義的時候加個var,這個可以記一下

var running struct {

     sync.Mutex

     cmd *exec.Cmd

}

 

繼續看compile,這個時候,參數request里面是包含要運行的go代碼

先將go代碼放到臨時文件中,然后bin是目標生成文件,src是源碼文件

第一步,將代碼寫入到src中

第二步,運行go build,並使用-o 參數,將目標文件生成到bin中

第三步,運行bin,輸出結果(當然這個結果是有做一些處理,之類的commentRe的作用)

第四步,刪除src和bin這兩個文件

 

下面就看fmt.go

對代碼進行格式化應該也可以使用go fmt工具,但是這里不是這樣使用的。

同goplay.go一樣,在init的時候設置了一個Handle

然后使用gofmt函數對代碼格式化,進到gofmt函數

gofmt函數使用了go/token,go/parser對代碼進行格式化,實際的工作就是:

1 順序化import包

2 美化go代碼

 

哈哈,這里就是說go的程序能對自身(go程序)進行美化和運行(自舉),這個感覺太爽了,使用的就是go/XXX的包

這里的幾個關鍵函數:

token.NewFileSet() : 創建fset結構

parser.ParseFile() : 解析go編碼(這步最后的mode能制定是解析到什么地步)

ast.SortImports() : 將import包進行排序

printer.Fprint() : 美化工具

這下代碼就結束了,至於頁面上出現的分頁的效果等,都是js和css作用的結果,與服務器無關了。

整個頁面只需要3個代碼文件(靜態頁面除外)!300行代碼不到的量!(當然它更多的操作是在js中)少即是極多!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM