[golang note] 包和導入


package的作用


       √ package是golang最基本的分發單位工程管理中依賴關系的體現

       √ 每個golang源代碼文件開頭都擁有一個package聲明,表示該golang代碼所屬的package。

       √ 要生成golang可執行程序,必須建立一個名為main的package,並且在該package中必須包含一個名為main()的函數

       √ 在golang工程中,同一個路徑下只能存在一個package,一個package可以拆成多個源文件組成。

       √ import關鍵字導入的是package路徑,而在源文件中使用package時,才需要package名。經常可見的import的目錄名和源文件中使用的package名一致容易造成import關鍵字后即是package名的錯覺,真正使用時,這兩者可以不同。

        

• 《Go語言編程》中calc實例

▶ 工程目錄

       <calcproj>
           ├─<src>
                   ├─<calc>
                            ├─calc.go
                   ├─<simplemath>
                            ├─add.go
                            ├─add_test.go
                            ├─sqrt.go
                            ├─sqrt_test.go
           ├─<bin>
           ├─<pkg>

▶ 詳細源碼

       Δ add.go

package sm

func Add(a int, b int) int {
    return a + b
}

       Δ sqrt.go

package sm

import "math" func Sqrt(i int) int {
    v := math.Sqrt(float64(i))
    return int(v)
}

       Δ add_test.go

package sm

import "testing" func TestAdd1(t *testing.T) {
    r := Add(1, 2)

    if r != 3 {
        t.Errorf("Add(1, 2) failed. Got %d, expected 3.", r)
    }
}

       Δ sqrt_test.go

package sm

import "testing" func TestSqrt1(t *testing.T) {
    v := Sqrt(16)

    if v != 4 {
        t.Errorf("Sqrt(16) failed. Got %v, expected 4.", v)
    }
}

       Δ calc.go

package main

import "os" import "fmt" import "strconv" import "simplemath"

var Usage = func() {
    fmt.Println("USAGE: calc command [arguments] ...")
    fmt.Println("\nThe commands are:\n\tadd\tAddition of two values.\n\tsqrt\tSquare root of a non-negative value.")
}

func main() {
    args := os.Args
    if args == nil || len(args) < 2 {
        Usage()
        return
    }

    switch args[1] {
    case "add":
        if len(args) != 4 {
            fmt.Println("USAGE: calc add <integer1> <integer2>")
            return
        }

        v1, err1 := strconv.Atoi(args[2])
        v2, err2 := strconv.Atoi(args[3])
        if err1 != nil || err2 != nil {
            fmt.Println("USAGE: calc add <integer1> <integer2>")
            return
        }

        ret := sm.Add(v1, v2)
        fmt.Println("Result: ", ret)
    case "sqrt":
        if len(args) != 3 {
            fmt.Println("USAGE: calc sqrt <integer>")
            return
        }

        v, err := strconv.Atoi(args[2])
        if err != nil {
            fmt.Println("USAGE: calc sqrt <integer>")
            return
        }

        ret := sm.Sqrt(v)
        fmt.Println("Result: ", ret)
    default:
        Usage()
    }
}

▶ 源碼說明

       calcproj工程中src\simplemath目錄下只存在sm一個package,而sm包由四個源文件構成。calc.go文件中可以看到import導入的是simplemath而非sm,而在使用sm包中的Add和Sqrt函數時,使用的才是真正的包名sm。

import關鍵字


        使用import語句導入源代碼文件所依賴的package路徑

       √ 不得導入源代碼文件中沒有用到的package,否則golang編譯器會報編譯錯誤。

• import語法

▶ 風格一

import "package1" import "package2" import "package3"
...

▶ 風格二

import (
    "package1"
    "package2"
    "package3"
    ...
)

• import原理

       如果編譯時main包導入了其他的包,那么這些包將被依次導入。

       當一個包被導入時,如果該包還導入了其它的包,那么先將其他的包導入進來,然后再對該包的包級常量和變量進行初始化,最后執行init函數(如果存在)。包的導入如上圖所示,是一個遞歸地過程,等所有被導入的包加載完畢,就會對main包中的包級常量和變量進行初始化,然后執行main包中的init函數(如果存在),最后執行main函數。

       如果一個包被多個包同時導入,那么它只會被導入一次。

• import修飾操作

• 點(.)操作

       點(.)操作的含義是:點(.)標識的包導入后,調用該包中函數時可以省略前綴包名。點(.)操作的語法為:

import . "package1" import . "package2" import . "package3"
...
import (
    . "package1"
    . "package2"
    . "package3"
    ...
)

       下面的示例中,fmt包將使用點操作省略前綴包名,os包用法保持不變:

package main

import (
    . "fmt"
    "os"
)

func main() {
    for _, value := range os.Args {
        Println(value)
    }
}

• 別名操作

       別名操作的含義是:將導入的包命名為另一個容易記憶的別名。別名操作的語法為:

import p1 "package1" import p2 "package2" import p3 "package3"
...
import (
    p1 "package1"
    p2 "package2"
    p3 "package3"
    ...
)

       下面的示例中,fmt包將使用別名操作重新命名為f,os包用法保持不變:

package main

import (
    f "fmt"
    "os"
)

func main() {
    for _, value := range os.Args {
        f.Println(value)
    }
}

• 下划線(_)操作

       下划線(_)操作的含義是:導入該包,但不導入整個包,而是執行該包中的init函數,因此無法通過包名來調用包中的其他函數。使用下划線(_)操作往往是為了注冊包里的引擎,讓外部可以方便地使用。下划線(_)操作的語法為:

import _ "package1" import _ "package2" import _ "package3"
...
import (
    _ "package1"
    _ "package2"
    _ "package3"
    ...
)

 


免責聲明!

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



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