go包的理解

结论:node

  1. import时指定的字符串,是相对于$GOPATH的目录路径,告诉了go,要去加载这个目录下全部的包文件(不包括子目录中的文件)
  2. 一个目录中全部的源文件(不包括子目录)表明了单独的一个包,这些源文件内的package关键字指出的包名,必须一致,不然没法被使用
  3. import指定的加载目录、目录中的源文件名字、源文件内经过package关键字指定的包名。这三者能够不同。导入后,根据package指定的包名,来使用包中的导出成员。
  4. 导入两个目录,这两个目录中的源文件内指定的包名,若是出现相同,则导入目录时会失败
  5. 同一个包,间接或直接被导入屡次。这个包只会被初始化一次。如init执行一次,包级别变量的内存只会被分配一次,后续要使用的话,则继续使用上次分配时的值。(这个规律和nodejs也是一致的)这也就是为何使用mysql时,要导入两个包:
    1. import "database/sql" import _ "github.com/go-sql-driver/mysql"
    2.  第二个包中引用了第一个包,init函数中对第一个包里的数据进行了一些mysql相关的操做。使后续直接使用第一个包时,能关联得上mysql。
    3. 导入第二个包仅仅是为了执行里面的init函数,从而影响第一个包的行为。因此第二个包空导入便可
  6. 当源文件被加载时,文件内的init函数会被自动执行:
    1. 经过import来加载一个目录时,若是这个目录中有多个源文件,则这些源文件中的init函数都会执行,但文件之间的init函数的执行次序不肯定,看go加载文件是的顺序
    2. 一个源文件内能够定义多个init函数,多个init函数会按顺序从上往下执行。虽然一个文件内能够定义多个init,可是没有这个必要,把逻辑都集中在一个init函数中,效果同样

测试1

$GOPATH目录以下:mysql

├─pkg
└─src
  └─app.go
  └─m1
    └─k1.gogit

app.go:github

package main

import "m1"

func main() {
    x1.Show()
}

 k1.go:sql

package x1

import "fmt"

func Show(){
    fmt.Println("show call")
}

 运行app.go:输出 show call。app

测试2

在以上的m1目录中,建立一个文件k2.go函数

package x2

import "fmt"

func Show(){
    fmt.Println("show call")
}

运行app.go提示:app.go:3:8: found packages x1 (k1.go) and x2 (k2.go) in D:\GoPath\src\m1测试

测试3

k1和k2文件中,都经过package指定包名为x1。app.go中导入这两个目录,运行报错:spa

.\app.go:4:8: x1 redeclared as imported package name
previous declaration at .\app.go:3:8
.\app.go:7:2: undefined: "m2".FnInK13d

 解决办法:导入的时候,将冲突的包名,重命名为另外一个值便可,如如下k2pkg

 测试4

k1.go:

package x1

import "fmt"

var x1Data int = 1;

func init(){
    fmt.Println("x1 init call")
    x1Data = 2;
}

func ShowData(){
    fmt.Println(x1Data)
}

func SetData(x int){
    x1Data = x;
}

k2.go:

package x2

import "m1"
import "fmt"

func init(){
    fmt.Println("x2 init call")
    x1.SetData(333)
}

app.go:

package main

import _ "m2"
import "m1"

func main() {
    x1.ShowData()
}

> go run app.gox1 init callx2 init call333

相关文章
相关标签/搜索