Go語言套件管理(一)

來源:互聯網
上載者:User
Go語言中的包

我們在使用其他語言,比如Java,Python,都有類似包的概念,Go也不例外,其核心思想即為分組和模組化。人的大腦對龐大和複雜的事情很難掌控,可以對其採用分而治之的策略,使其模組化,從而更容易管理。 如下是標準庫中net包的樹形結構圖

net
├─http
│ ├─cgi
│ │ └─testdata
│ ├─cookiejar
│ ├─fcgi
│ ├─httptest
│ ├─httptrace
│ ├─httputil
│ ├─internal
│ ├─pprof
│ └─testdata
├─internal
│ └─socktest
├─mail
├─rpc
│ └─jsonrpc
├─smtp
├─testdata
├─textproto
└─url 庫包和main包

當把一個程式的package聲明為main的時候(並且該檔案包含一個main函數),則表示最終該程式要編譯為一個可執行檔程式。如果程式未聲明為main,則可以編譯為一個庫的形式。 包的匯入

通過import匯入包之後,即可使用包中的變數和函數,如下源碼,我們定義了一個lib包,裡面定義了加,減,乘,除4個方法,然後在另一個包中來使用。

庫中的內容如下:

package lib1func Add(x, y int) int {    z := x + y    return z}func Sub(x, y int) int {    z := x - y    return z}func Mul(x, y int) int {    z := x * y    return z}func Div(x, y int) int {    z := x / y    return z}

main包的內容如下:

package mainimport (    "fmt"    "lib1")func main() {    x := 8    y := 2    a := lib1.Add(x, y)    b := lib1.Sub(x, y)    c := lib1.Mul(x, y)    d := lib1.Div(x, y)    fmt.Println(a)    fmt.Println(b)    fmt.Println(c)    fmt.Println(d)}

輸出:

10
6
16
4

注意庫包中匯出的方法若想讓包外可見,則第一個字母要大寫。如Add,Sub… 否則該方法對包外不可見,僅可在本包中使用(變數也有同樣的原則)。Go語言沒有提供類似C++和Java的private,public,protected等關鍵字,也反應了Go語言的哲學思想:簡單實用至上。 包名匯入衝突(命名匯入)

在使用import匯入包的時候,我們就可以通過包名稱引用包中的方法,如上面的lib1,但是如果有又有另一個人開發的包名稱也為lib1(這裡只包的最後一部分),也就是發生的包命名衝突該如何處理呢。可以在import的名稱前面起一個別名處理此問題,如下分別把“fmt”和“lib1”的包名稱重新命名為了“fmta”和“liba”

package mainimport (    fmta "fmt"    liba "lib1")func main() {    x := 8    y := 2    a := liba.Add(x, y)    b := liba.Sub(x, y)    c := liba.Mul(x, y)    d := liba.Div(x, y)    fmta.Println(a)    fmta.Println(b)    fmta.Println(c)    fmta.Println(d)}
包的初始化函數 init()

一個包中可能有多個檔案,如果我們想對這個包做一些初始化操作該如何做呢。Go提供了一個既沒有參數也沒有傳回值的init()函數(類似main函數), 可以在init函數中進行初始化操作。 比如有如下3個包“lib1”,“lib2”“m1”分別代表兩個庫包和一個包含main函數的主包,每個包中有對應的Go檔案,包目錄結構如下:

├─lib1 a.go
├─lib2 b.go
└─m1 m.go

“m1”包中的m.go檔案會import“lib1”,進一步“lib1”會import“lib2”。且在lib1和lib2中定義了init函數。源碼如下:

//lib2中的a2.gopackage lib2import (    "fmt")func init() {    fmt.Println("lib2 init1")}func init() {    fmt.Println("lib2 init2")}
// lib1中的a1.gopackage lib1import (    "fmt"    _ "lib2")func init() {    fmt.Println("lib1 init1")}func init() {    fmt.Println("lib1 init2")}
//m1中的m.gopackage mainimport (    "fmt"    _ "lib1")func main() {    fmt.Println("main")}

輸出:

lib2 init1
lib2 init2
lib1 init1
lib1 init2
main

可見main最後執行,首先執行的是import各個包時候的init。而且init函數執行的順序是依據依賴順序來執行的。Go會遞迴對依賴進行分析,然後從main包開始分析,首先保證沒有循環相依性。main包發現import了“lib1”,lib1發現又import了“lib2”,因此首先執行lib2的init函數,再返回執行lib1中的init函數,最後返回到main函數來執行。

每個包中可以有多個檔案,每個檔案中也可以有多個init()函數,但是這些init函數的順序Go是沒有保證的。 包的匿名匯入

因為Go對匯入但是未使用的包,會報編譯錯誤。因此可以使用如下的方式。在包名稱之前使用一個底線”_”來表示。這樣仍然會執行所import包中的init函數。

package lib1import (    "fmt"    _ "lib2")
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.