1. 程式人生 > 其它 >(十五)Golang基礎之包

(十五)Golang基礎之包

在工程化的Go語言開發專案中,Go語言的原始碼複用是建立在包(package)基礎之上的。本文介紹了Go語言中如何定義包,如何匯出包的內容及如何匯入其他包。

一、包介紹

包(package)是多個Go原始碼的集合,是一種高階的程式碼複用方案,Go語言為我們提供了很多內建包,如fmt、os、io等。

二、定義包

我們還可以根據自己的需要建立自己的包。一個包可以簡單理解為一個存放.go檔案的資料夾。 該資料夾下面的所有go檔案都要在程式碼的第一行新增如下程式碼,宣告該檔案歸屬的包。

package 包名

注意事項:

  • 一個資料夾下面直接包含的檔案只能屬於一個package,同樣一個package的檔案不能在多個資料夾下。
  • 包名可以不和資料夾名一樣,報名不能包含-符號
  • 包名為main的包為應用程式入口包,這種包編譯後會得到一個可執行檔案,而編譯不包含main包的原始碼則不會得到可執行檔案。

三、可見性

如果想在一個包中引用另外一個包裡的識別符號(如變數、常量、型別、函式等)時,該識別符號必須是對外可見的(public)。在Go語言中只需要將識別符號的首字母大寫就可以讓識別符號對外可見了。
舉個例子, 我們定義一個包名為pkg2的包,程式碼如下:

package pkg2
import "fmt"
// 包變數可見性
var a = 100 // 首字母小寫,外部包不可見,只能在當前包內使用
// 首字母大寫外部包可見,可在其他包中使用
const Mode = 1
type person struct { // 首字母小寫,外部包不可見,只能在當前包內使用
	name string
}
// 首字母大寫,外部包可見,可在其他包中使用
func Add(x, y int) int {
	return x + y
}
func age() { // 首字母小寫,外部包不可見,只能在當前包內使用
	var Age = 18 // 函式區域性變數,外部包不可見,只能在當前函式內使用
	fmt.Println(Age)
}

結構體中的欄位名和介面中的方法名如果首字母都是大寫,外部包可以訪問這些欄位和方法。例如:

type Student struct {
	Name  string //可在包外訪問的方法
	class string //僅限包內訪問的欄位
}
type Payer interface {
	init() //僅限包內訪問的方法
	Pay()  //可在包外訪問的方法
}

四、包的匯入

要在程式碼中引用其他包的內容,需要使用import關鍵字匯入使用的包。具體語法如下:

import "包的路徑"

注意事項:
• import匯入語句通常放在檔案開頭包宣告語句的下面。
• 匯入的包名需要使用雙引號包裹起來。
• 包名是從$GOPATH/src/後開始計算的,使用/進行路徑分隔。
• Go語言中禁止迴圈匯入包。

1、單行匯入

單行匯入的格式如下:

import "包1"
import "包2"

2、多行匯入

多行匯入的格式如下:

import (
    "包1"
    "包2"
)

五、自定義包

在匯入包名的時候,我們還可以為匯入的包設定別名。通常用於匯入的包名太長或者匯入的包名衝突的情況。具體語法格式如下:
import 別名 "包的路徑"
單行匯入方式定義別名:

import "fmt"
import m "github.com/Q1mi/studygo/pkg_test"
func main() {
	fmt.Println(m.Add(100, 200))
	fmt.Println(m.Mode)
}

多行匯入方式定義別名:

import (
    "fmt"
    m "github.com/Q1mi/studygo/pkg_test"
 )
func main() {
	fmt.Println(m.Add(100, 200))
	fmt.Println(m.Mode)
}

六、匿名匯入包

如果只希望匯入包,而不使用包內部的資料時,可以使用匿名匯入包。具體的格式如下:

import _ "包的路徑"

匿名匯入的包與其他方式匯入的包一樣都會被編譯到可執行檔案中。

七、init()初始化函式

1、init()函式介紹

在Go語言程式執行時匯入包語句會自動觸發包內部init()函式的呼叫。需要注意的是: init()函式沒有引數也沒有返回值。 init()函式在程式執行時自動被呼叫執行,不能在程式碼中主動呼叫它。
包初始化執行的順序如下圖所示:

2、init()函式執行順序

Go語言包會從main包開始檢查其匯入的所有包,每個包中又可能匯入了其他的包。Go編譯器由此構建出一個樹狀的包引用關係,再根據引用順序決定編譯順序,依次編譯這些包的程式碼。
在執行時,被最後匯入的包會最先初始化並呼叫其init()函式,如下圖示: