【Golang】导入自定义包
概述
我在以下的目录结构下,进行了使用Go进行编码的工作。
在那个时候,我遇到了一个独特包的导入问题,所以我将解决方法记录下来。
前提
目錄結構設置如下。
~/
code/
src/
ruby/
swift/
kotlin/
javascript/
...
golang/
repo1/
repo2/
...
repo10/
main.go # エントリーポイントのファイル
sub.go # mainパッケージ内の関数群
readme.md
package1/ # 自作パッケージのディレクトリ
package1.go
package2/ # 自作パッケージのディレクトリ
package2.go
...
每个文件都按照以下方式进行了处理。
package main
func main() {
doSomething()
}
package main
// 最初に書いた呼び出し方。
// これでは呼び出せない。
import "package1"
func doSomething() {
// 独自パッケージ内の関数を呼び出す
package1.OriginalPackageFunction()
}
package package1
func OriginalPackageFunction() {
// do something.
}
我已经设置了GOPATH如下。
$GOPATH = "$HOME/code"
错误 (wù)
当使用`go run mai.go sub.go`来运行时,会出现如下错误。
sub.go:3:2: cannot find package "package1" in any of:
/PATH/OF/YOUR/GOROOT/src/package1 (from $GOROOT)
/PATH/OF/YOUR/GOPATH/src/package1 (from $GOPATH)
从这个结果可以看出,在Golang中导入包时,会搜索以下目录。
$GOROOT/src 配下のパッケージ名のディレクトリの中
$GOPATH/src 配下のパッケージ名のディレクトリの中
解决的要点 (jiě jué de
Golang 中的包导入与 Gopher 如何交换包相关。
在Golang中,使用go get命令获取外部包。
如果想要使用在Github上公开的go-kit/kit软件包,
去获取github.com/go-kit/kit。
可以使用该命令获取软件包。
具体而言,在$GOAPTH/src目录下,克隆指定的存储库。
简单来说,执行go get github.com/go-kit/kit命令后,会生成以下目录结构。
~/
code/
src/
ruby/
swift/
kotlin/
javascript/
...
+ github.com/ # ここにクローンされる
+ go-kit/
+ kit/
+ ...
golang/
repo1/
repo2/
...
repo10/
main.go # エントリーポイントのファイル
sub.go # mainパッケージ内の関数群
readme.md
package1/ # 自作パッケージのディレクトリ
package1.go
package2/ # 自作パッケージのディレクトリ
package2.go
...
go get github.com/go-kit/kit
go工具将从托管在https://github.com/go-kit/kit/的项目中获取源代码。它将克隆该存储库到
$GOPATH/src/github.com/go-kit/kit
因此,如果在你的存储库项目中导入了一个在同一个存储库中的包,你需要使用它的“完整”导入路径 – 即”go get”放置的位置。在这个例子中,如果其他项目想要导入“kit”包,它应该导入“github.com/go-kit/kit”而不是“kit”。
解决方案 cè’àn)
最佳方法是将工作目录更改为$GOPATH/src以下与自己的远程存储库URL相同。
假设你在 GitHub 上管理仓库,那么 URL 就会是 github.com/用户名/仓库名。对于本示例来说,
~/
code/
src/
ruby/
swift/
kotlin/
javascript/
...
golang/
src/
+ github.com/
+ username/
repo1/
repo2/
...
repo10/
main.go
sub.go
readme.md
package1/
package1.go
package2/
package2.go
...
在这样的背景下,
$GOPATH="$HOME/code/src/golang/"
重新贴上。
然后,重新编写导入语句。
// sub.go
package main
// これで呼び出せる。
import "github.com/username/repo10/package1"
func doSomething() {
// 独自パッケージ内の関数を呼び出す
package1.OriginalPackageFunction()
}
填補 1
在其他语言中,可以使用相对路径指定外部模块并进行导入。
在Golang中,也可以使用相对路径进行导入。
import "./package1"
这个方法不被推荐。
尤其是在go test等情况下,使用相对路径进行导入。
local import "./package1" in non-local package
是的。
補充2
看起来也可以将多个包放在一个目录中。
~/
code/
src/
ruby/
swift/
kotlin/
javascript/
...
golang/
src/
github.com/
username/
repo1/
repo2/
...
repo10/
main.go
sub.go
readme.md
+ original_packages/
+ package1.go
+ package2.go
+ ...
然而,在这种情况下,import语句会略有不同。
// sub.go
package main
// パスの前にパッケージ名を記述する。
import package1 "github.com/username/repo10/original_package"
func doSomething() {
// 独自パッケージ内の関数を呼び出す
package1.OriginalPackageFunction()
}