Aaffo 原创

1 minute read

现在项目基本都用go mod了,但是go mod还有有点问题的,如果你现在有个模块要导入本地其他项目里的包, go mod的处理感觉就有点不合理。

├─test
│      go.mod
│      main.go
│      
├─test1
│      go.mod
│      test1.go
//test1.go
package test1

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

比如现在test包要使用test1包,就需要两个项目都使用go mod。并且需要这样导入:

//main.go
package main

import (
	"fmt"
	"github.com/test1"
)
func main() {
	fmt.Println(test1.Add(1,2))
}

go.mod:

module test

go 1.13

require github.com/test1 v0.0.0-incompatible

replace github.com/test1 => ../test1

否则不管怎么导入总会报一些错误比如:

package test1 is not in GOROOT

test1: parsing ..\test1\go.mod: open G:\go\src\test1\go.mod: The system cannot find the file specified.

malformed module path "test1": missing dot in first path element

为什么要在前缀加上github.com/,因为go module 名称规范要求路径的第一部分必须满足域名规范 这里第三个错误就是报的这个错。

更蛋疼的还在后面,如果test1又import了test2包:

├─test
│      go.mod
│      main.go
│      
├─test1
│      go.mod
│      test1.go
│      
├─test2
│      go.mod
│      test2.go
//test1.go
package test1

import (
	"github.com/test2"
)

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

func Test(a,b int) int {
	return Add(a,b)+test2.Sub(a,b)
}

并且test1的go mod也用了同样方法加入了require & replace

module test1

go 1.13

require github.com/test2 v0.0.0-incompatible

replace github.com/test2 => ../test2

那么此时的test项目的go mod就需要写成

module test

go 1.13

require github.com/test1 v0.0.0-incompatible

replace github.com/test1 => ../test1

replace github.com/test2 => ../test2

否则还会报错:github.com/test2@v0.0.0-incompatible: invalid github.com/ import path "github.com/test2"

在代码托管平台的代码不存在这个问题,不过本地包一定要这样导入总是怪怪的。

Go版本升级-后续

现在版本升级到go1.14.1了,此问题好像改善了一点,但是还是挺麻烦的。单次导入需要这样写:

//main.go
import "test1" 

//go.mod 
module test

go 1.14

replace test1 => ../test1

然后执行go mod tidy,go.mod 会自动添加一行

require test1 v0.0.0-00010101000000-000000000000

嵌套导入本地模块的话,需要在go.mod中指出用到本地包的路径:

module test

go 1.14

replace test1 => ../test1

replace test2 => ../test2

起码没有奇怪的github.com前缀了,算是还行吧。

comments powered by Disqus