目录
一、package
1、什么是package
是 Go 语言中的基本可复用模块儿,可以类比 PHP 里面某个命名空间,import 一个包,就相当于 use 一个命名空间进来。
2、Go的包管理方案
Go有 GOMOD 和 GOPATH 两种包管理方案,互不兼容。
- 在 GOPATH 下查包,按照 GOROOT 和多个 GOPATH 目录下的 src/xxx 依次查找。
- 在 GOMOD 下查包,解析 go.mod 文件,mod 包名就是报的前缀,里面的目录就是后续路径。
a、在 GOPATH 下查包
我们需要检查一下 GO111MODULE 是否为 off,只有关闭了 GOMOD 模式,才能使用 GOPATH 模式。
//查看 Go 的环境变量,GO111MODULE是否为off
go env
如果 GO111MODULE=on, 通过执行如下命令就行修改
//关闭 GOMOD 模式
go env -w GO111MODULE=OFF
如果执行报 does not override conflicting OS environment varia 错误,则需要修改我们电脑的环境变量。
//mac 在 ~/.bash_profile 文件修改
export GO111MODULE=off
修改完毕后需要先执行 source ~/.bash_profile 然后重启 IDE 才会生效,在用 go env 确认一下是否已生效。
然后用同样的方法把我们的项目文件夹添加到 GOPATH 里面去,加进去后,Go 才能在找到我们自定义的 package。
//把我们的项目目录添加到 GOPATH
export GOPATH="$HOME/wwwroot/go_learning"
当然也可以直接在 IDE 上面添加,例如 GoLand 的添加位置如下:
b、在 GOMOD 下查包
//TODO
3、Go的package具有的特点
- package中的方法以⾸字⺟⼤写来表明可被包外代码访问;
- 代码的 package 可以和所在的⽬录不⼀致;
- 同⼀⽬录⾥的 Go 代码的 package 要保持⼀致。
4、调用示例
//这是我们自定义的一个包,一会儿会通过包外的函数调用这个包里面的方法
package series
//生成斐波拉西数列
func GetFibonacciSeries(num int) []int {
var FibList = []int{1, 1}
for i := 2; i < num; i++ {
FibList = append(FibList, FibList[i-2] + FibList[i-1])
}
return FibList
}
//求某个数的平方
func square(num int) int {
return num * num
}
//我们将在这个包里面调用自定义的 series 包
package client
import (
//注意这里引入路径的格式,是从 src 的下一级目录开始
"ch15/series"
"testing"
)
//调试引入自定义的包,并调用里面的方法
func TestPackage(t *testing.T) {
//可以调用自定义包已大写字母开头的方法
series := series.GetFibonacciSeries(10)
t.Log(series)
//不能调用自定义包已小写字母开头的方法
//series.square(10)
}
二、init 方法
- 在 main 被执行前,所有依赖的 package 的 init 方法都会被执行;
- 不同包的 init 函数按照包导入的依赖关系决定执行顺序;
- 每个包可以有多个 init 函数;
- 包的每个源⽂件也可以有多个 init 函数,这点⽐较特殊。
package series
import "fmt"
//第一个 init 方法,会被先执行
func init() {
fmt.Println("init 1")
}
//生成斐波拉西数列
func GetFibonacciSeries(num int) []int {
var FibList = []int{1, 1}
for i := 2; i < num; i++ {
FibList = append(FibList, FibList[i-2] + FibList[i-1])
}
return FibList
}
//求某个数的平方
func square(num int) int {
return num * num
}
//第二个 init 方法,会紧接第一个init 方法执行
func init() {
fmt.Println("init 2")
}
/*
执行结果:
init 1
init 2
=== RUN TestPackage
package_test.go:12: [1 1 2 3 5 8 13 21 34 55]
--- PASS: TestPackage (0.00s)
PASS
*/
三、使用远程 package
1、go get 拉取远程 package
通过 go get 来拉取我们想要的远程 package, 如果每次都想要从网上去更新最新版,则加入 -u 这个参数。
//注意:复制 github 地址后,需要删除前面的 https:// 和后面的 .git,否则会报错
go get -u github.com/easierway/concurrent_map
报错1:
invalid import path: malformed import path "https:/github.com/easierway/concurrent_map.git":
invalid char ':'
解决方法:删掉前面的 https://
报错2:
package github.com/easierway/concurrent_map.git:
invalid version control suffix in github.com/ path
解决方法:删掉后面的的 .git
2、使用远程 package
package remote_package
import (
//可以给包名起别名
cm "github.com/easierway/concurrent_map"
"testing"
)
//调试引入远程的包
func TestRemotePackage(t *testing.T) {
concurrent := cm.CreateConcurrentMap(99)
concurrent.Set(cm.StrKey("key"), 10)
t.Log(concurrent.Get(cm.StrKey("key")))
}
/*
执行结果:
=== RUN TestRemotePackage
remote_package_test.go:11: 10 true
--- PASS: TestRemotePackage (0.00s)
PASS
*/
3、提交自己的 package 到github
需要自己的代码在 github 上的组织形式,以适应 go get ,一定要直接已代码路径开始,不要有 src
四、总结
- Go有 GOMOD 和 GOPATH 两种包管理方案,互不兼容;
- 在 GOPATH 下查包,按照 GOROOT 和多个 GOPATH 目录下的 src/xxx 依次查找;
- 在 GOMOD 下查包,解析 go.mod 文件,mod 包名就是报的前缀,里面的目录就是后续路径。
- package中的方法以⾸字⺟⼤写来表明可被包外代码访问;
- 代码的 package 可以和所在的⽬录不⼀致;
- 同⼀⽬录⾥的 Go 代码的 package 要保持⼀致。
- 在 main 被执行前,所有依赖的 package 的 init 方法都会被执行;
- 不同包的 init 函数按照包导入的依赖关系决定执行顺序;
- 每个包可以有多个 init 函数;
- 包的每个源⽂件也可以有多个 init 函数。
- go get 的格式:go get -u github.com/easierway/concurrent_map。
- 自己的代码提交到 github,一定要直接已代码路径开始,不要有 src。
注:这篇博文是我学习中的总结,如有转载请注明出处:
https://blog.csdn.net/DaiChuanrong/article/details/118197164
上一篇:Go-错误处理
下一篇:Go-依赖管理