如何进口本地包裹?

我是新来的,去和工作的一个示例代码,我想本地化。

在原来的 main.go进口报表中,它是:

 import (
"log"
"net/http"
"github.com/foo/bar/myapp/common"
"github.com/foo/bar/myapp/routers"
)

现在我有 commonrouters/home/me/go/src/myapp

所以我将 import 语句转换为:

import (
"log"
"net/http"
"./common"
"./routers"
)

但是当我运行 go install myapp时,我会得到这些错误:

can't load package: /home/me/go/src/myapp/main.go:7:3: local import "./common" in non-local package

另外,当我在 import 语句中使用 commonrouters而不是 ./common./routers时,我得到:

myapp/main.go:7:3: cannot find package "common" in any of:
/usr/local/go/src/common (from $GOROOT)
/home/me/go/src/common (from $GOPATH)
myapp/main.go:8:2: cannot find package "routers" in any of:
/usr/local/go/src/routers (from $GOROOT)
/home/me/go/src/routers (from $GOPATH)

我该怎么补救?

271307 次浏览

导入路径与 $GOPATH$GOROOT环境变量相关:

GOPATH=/home/me/go

位于 /home/me/go/src/lib/common/home/me/go/src/lib/routers的软件包分别按以下方式进口:

import (
"lib/common"
"lib/routers"
)

我找到问题所在了。 基本上导入的起始路径是 $HOME/go/src

所以我只需要在包名前面添加 myapp,也就是说,导入应该是:

import (
"log"
"net/http"
"myapp/common"
"myapp/routers"
)

如果您正在使用上面的 Go 1.5,您可以尝试使用 小贩特性。 它允许您将您的本地包放在 供应商文件夹下,并以较短的路径导入它。 在您的情况下,您可以把您的 很普通路由器文件夹内的 供应商文件夹 所以就像是

myapp/
--vendor/
----common/
----routers/
------middleware/
--main.go

然后像这样进口

import (
"common"
"routers"
"routers/middleware"
)

这将工作,因为围棋将尝试查找您的软件包开始在您的项目的供应商目录(如果它至少有一个。Go file)而不是 $GOPATH/src。

供参考: 你可以对供应商做更多的事情,因为这个特性允许你把“所有你依赖的代码”放在你自己项目的目录中,这样它就可以为所有的构建获得相同的依赖版本。它类似于 python 中的 npm 或 pip,但是您需要手动将您的依赖项复制到您的项目中,或者如果您想让它变得简单,请尝试查看 Daniel Theophanes 的 govendor

要了解更多关于这个特性的信息,请尝试查看这里

理解和使用供应商文件夹

理解 Go 依赖管理卢卡斯 · 费尔南德斯 · 达 · 科斯塔

我希望你或者其他人能帮上忙

本地包是一个恼人的问题在去。

对于我们公司的一些项目,我们决定根本不使用子包。

  • $ glide install
  • $ go get
  • $ go install

都是工作。

对于某些项目,我们使用子包,并导入具有完整路径的本地包:

import "xxxx.gitlab.xx/xxgroup/xxproject/xxsubpackage

但是,如果我们分支这个项目,那么子包仍然引用原来的一个。

例如:

  1. ./greetings,做 go mod init example.com/greetings

  2. 从另一个模块,做 go mod edit -replace=example.com/greetings=../greetings

  3. go get example.com/greetings

去补习

您应该已经使用 go mod init(例如 go mod init github.com/my-org/my-package)创建了包

例如,在 my-package中有一个称为 utils的子模块。

main.go
utils
|- randstr.go

你的 randstr.go是这样的:

package utils


func RandStr(n int) string {
// TODO: Generate random string....
return "I am a random string"
}

然后在你的应用程序的任何地方,你都可以像这样使用从 utils包导出的函数,例如在 main.go中:

package main


import (
"fmt"


// "github.com/my-org/my-package" is the module name at the
// top of your `go.mod`
"github.com/my-org/my-package/utils"
)


func main() {
fmt.Printf("Random string: %s\n", utils.RandStr(20))
}

关键是如何在下面的命令中命名模块

go mod init <TheNameGiven>

然后引用内部文件夹中的模块,

TheNameGiven/folder

我已经找到了最好的解决方案... 阅读更多

正如问题所示,文件夹结构是:

/home/me/go/src/myapp
└─ common
└─ routers

所以去 我的应用目录

cd /home/me/go/src/myapp

go mod init myapp

这将创建一个 去吧 Mod文件,该文件让 Go 知道模块 我的应用的名称,以便在查看任何包中的导入路径时,它知道不要在其他地方查找 我的应用

然后您可以在代码中执行以下操作:

import (
"log"
"net/http"
"myapp/common"
"myapp/routers"
)

现在,公共包和路由器被导入。

尝试使用 进行改进命令更改包名称。

所以,我有1.17,我有同样的导入问题。我的项目目录是 $GOPATH/src/myswagger/app-swagger-test。我在 虚张声势测试目录下运行这个命令:

go mod init app-swagger-test
go mod tidy

在我的新 go.mod 文件中,软件包的名称是 app-swagger-test:

import (
...
"myswagger/app-swagger-test/internal/generated/restapi"
"myswagger/app-swagger-test/internal/generated/restapi/operations"
)

所以我删除了 go.mod 和 go.sum,然后在 虚张声势测试目录下运行下面的命令:

go mod init myswagger/app-swagger-test
go mod tidy

之后,项目中的所有导入都成功导入:

module myswagger/app-swagger-test

也许这个信息是常见的,但我没有找到它。谢谢!

按照这里的指示 https://go.dev/doc/tutorial/call-module-code

主要是您需要在 go.mod 文件中执行替换调用。

module example.com/hello


go 1.16


replace example.com/greetings => ../greetings

go1.18以来可用的另一种方法是使用 go.work文件。

首先,本地 common包必须是一个模块,因此在 common文件夹中提供一个 go.mod文件:

module common


go 1.18

您现在可以在目录的根目录中手动创建一个 go.work文件,或者调用 go work init,然后是 go work use .,最后是 go work use ./common。它会像这样:

go 1.18


use (
.
./common
)

最后,您可以按名称在代码中导入包

package main


import "common"

只要记住不要提交 go.work文件:)