最近学习go语言,碰到需要import引用其他项目路径下的package,上网搜了好多帖子,发现实现方案都比较老了,考虑分享一期最新的跨项目路径import自定义包的学习经验。

1)代码结构和示例源码

.
└── src
    └── import_pkg
        └──import
            ├── main.go
            └── mypkg
                └── mypkg.go
        └──myapi
            ├── myapi.go

main.go代码如下:

package main

import (
	"import/mypkg"
	"myapi"
	"fmt"
)

func main() {

	mypkg.CustomPkgFunc()
	myapi.CustomApiFunc()
	fmt.Println("hello world")
}

mypkg.go代码如下:

package mypkg

import "fmt"

func CustomPkgFunc() {
	fmt.Println("call CustomPkgFunc")
}

myapi.go代码如下

package myapi

import "fmt"

func CustomApiFunc() {
	fmt.Println("call CustomApiFunc")
}

2)go,编译示例工程

在main.go所在的根目录,使用go mod init命令生成go.mod,使能go module功能。

重要:本人环境配置了GO111MODULE="auto",通过go mod init命令使能go module,配置命令:go env -w GO111MODULE=auto。
go module模式和GOPATH模式区别,参见 EmpShuai:新手上路go,项目编译踩过的坑

生成go.mod,mod名字根main.go文件中import "import/mypkg"里的import保持一致

$ go mod init import
go: creating new go.mod: module import
go: to add module requirements and sums:
	go mod tidy
$ go build -o main import
main.go:5:2: package myapi is not in GOROOT (/usr/local/go/src/myapi)

go build过程报错,编译器在GOROOT下找不到myapi这个package。类比c语言,我们需要告诉编译器main.go依赖的自定义包的路径。

通过修改go.mod,描述依赖包的路径。

module import

go 1.16

require myapi v0.0.0      //描述依赖的package名,v0.0.0用于网上版本的版本号,本地模式也要有
replace myapi => ../myapi //描述依赖的package所在的目录,../myapi就是路径。

执行编译命令,如下所是,运行成功。

$ go build -o main import
$ ls
go.mod  main  main.go  mypkg
$ go run main.go         
call CustomPkgFunc
call CustomApiFunc
hello world

3)拓展知识

go支持依赖的库为github等网络上的源码路径,依赖通过require和replace进行配置,示例。

require (
    golang.org/x/sys v0.0.0      
    cloud.google.com/go v0.34.0
)

replace (
    git.apache.org/thrift.git => git-wip-us.apache.org/repos/asf/thrift.git v0.12.0
    cloud.google.com/go => github.com/googleapis/google-cloud-go v0.37.0
)

require xxx.xxx v0.x.x:第一个参数是源文件中import 里使用的package名,第二个参数为网络上的版本号。

replace xxx.xxx => 源码链接:第一个参数是源文件中import 里使用的package名,第二个参数为网络上的源码链接。

备注:在 go1.13 中, go module 名称规范要求路径的第一部分必须满足域名规范(即使是本地package引用,也必须是网络域名的格式,比如http://github.com/myapi),否则可能汇报类似 malformed module path "article": missing dot in first path element 这样的错误。该问题在最新的go1.16版本中,已经修复,可以使用如上文所示的不带域名路径的package名。

尊重原创,严禁转载,谢谢!