英文:
How to import local packages in go?
问题
我是你的中文翻译助手,以下是翻译好的内容:
我刚开始学习Go,并且正在处理一个我想要本地化的示例代码。
在原始的 main.go
文件中,导入语句如下:
import (
"log"
"net/http"
"github.com/foo/bar/myapp/common"
"github.com/foo/bar/myapp/routers"
)
现在我在 /home/me/go/src/myapp
目录下有 common
和 routers
包。
所以我将导入语句改为:
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
另外,当我在导入语句中使用 common
和 routers
而不是 ./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)
我该如何解决这个问题?
英文:
I am new to go and working on an example code that I want to localize.
In the original main.go
import statement it was:
import (
"log"
"net/http"
"github.com/foo/bar/myapp/common"
"github.com/foo/bar/myapp/routers"
)
Now I have common
and routers
package in /home/me/go/src/myapp
So I converted the import statement to:
import (
"log"
"net/http"
"./common"
"./routers"
)
But when I run go install myapp
I get these errors:
can't load package: /home/me/go/src/myapp/main.go:7:3: local import "./common" in non-local package
Also, when I use common
and routers
instead of ./common
and ./routers
in the import statement, I get:
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)
How can I fix this?
答案1
得分: 139
嗯,我找到了问题所在。
基本上,Go语言的导入路径起始位置是$HOME/go/src
。
所以我只需要在包名前面添加myapp
,也就是导入应该是这样的:
import (
"log"
"net/http"
"myapp/common"
"myapp/routers"
)
英文:
Well, I figured out the problem.
Basically Go starting path for import is $HOME/go/src
So I just needed to add myapp
in front of the package names, that is, the import should be:
import (
"log"
"net/http"
"myapp/common"
"myapp/routers"
)
答案2
得分: 73
你应该使用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: 生成随机字符串....
return "我是一个随机字符串"
}
然后,在你的项目的任何地方,你可以像这样使用utils
包中的导出函数,例如在main.go
中:
package main
import (
"fmt"
// "github.com/my-org/my-package" 是你的`go.mod`文件顶部的模块名
"github.com/my-org/my-package/utils"
)
func main() {
fmt.Printf("随机字符串:%s\n", utils.RandStr(20))
}
英文:
You should have created your package with go mod init
e.g. go mod init github.com/my-org/my-package
Now in my-package
you have a sub module called utils
for example.
main.go
utils
|- randstr.go
And your randstr.go
looks like this:
package utils
func RandStr(n int) string {
// TODO: Generate random string....
return "I am a random string"
}
And then anywhere in your project you would use exported (capitalized) functions from the utils
package like this, for example in 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))
}
答案3
得分: 62
如果您使用的是Go 1.5以上的版本,可以尝试使用vendoring功能。它允许您将本地包放在vendor文件夹下,并使用更短的路径导入它。
在您的情况下,您可以将common和routers文件夹放在vendor文件夹内,就像这样:
myapp/
--vendor/
----common/
----routers/
------middleware/
--main.go
然后像这样导入它们:
import (
"common"
"routers"
"routers/middleware"
)
这样可以正常工作,因为Go会从您的项目的vendor目录开始查找您的包(如果它至少有一个.go文件),而不是$GOPATH/src。
顺便说一下:您可以在vendor中做更多的事情,因为这个功能允许您将“所有依赖包的代码”放在您自己项目的目录中,这样它将始终能够获取相同版本的依赖项。这有点像Python中的npm或pip,但您需要手动将依赖项复制到您的项目中,或者如果您想简化操作,可以尝试使用Daniel Theophanes的govendor工具。
要了解更多关于这个功能的信息,请参考以下链接:
Daniel Theophanes的《理解和使用Vendor文件夹》
Lucas Fernandes da Costa的《理解Go依赖管理》
希望对您或其他人有所帮助。
英文:
If you are using Go 1.5 above, you can try to use vendoring feature.
It allows you to put your local package under vendor folder and import it with shorter path.
In your case, you can put your common and routers folder inside vendor folder
so it would be like
myapp/
--vendor/
----common/
----routers/
------middleware/
--main.go
and import it like this
import (
"common"
"routers"
"routers/middleware"
)
This will work because Go will try to lookup your package starting at your project’s vendor directory (if it has at least one .go file) instead of $GOPATH/src.
FYI: You can do more with vendor, because this feature allows you to put "all your dependency’s code" for a package inside your own project's directory so it will be able to always get the same dependencies versions for all builds. It's like npm or pip in python, but you need to manually copy your dependencies to you project, or if you want to make it easy, try to look govendor by Daniel Theophanes
For more learning about this feature, try to look up here
Understanding and Using Vendor Folder by Daniel Theophanes
Understanding Go Dependency Management by Lucas Fernandes da Costa
I hope you or someone else find it helpfully
答案4
得分: 25
导入路径是相对于您的$GOPATH
和$GOROOT
环境变量的。例如,假设您的$GOPATH
如下所示:
GOPATH=/home/me/go
位于/home/me/go/src/lib/common
和/home/me/go/src/lib/routers
的包可以分别这样导入:
import (
"lib/common"
"lib/routers"
)
英文:
Import paths are relative to your $GOPATH
and $GOROOT
environment variables. For example, with the following $GOPATH
:
GOPATH=/home/me/go
Packages located in /home/me/go/src/lib/common
and /home/me/go/src/lib/routers
are imported respectively as:
import (
"lib/common"
"lib/routers"
)
答案5
得分: 13
一个例子:
-
在
./greetings
目录下,执行go mod init example.com/greetings
-
在另一个模块中,执行
go mod edit -replace=example.com/greetings=../greetings
-
执行
go get example.com/greetings
来自Go教程。
英文:
an example:
-
in
./greetings
, dogo mod init example.com/greetings
-
from another module, do
go mod edit -replace=example.com/greetings=../greetings
-
go get example.com/greetings
from the go tutorial
答案6
得分: 9
请按照这里的说明进行操作:https://go.dev/doc/tutorial/call-module-code
主要是需要在你的 go.mod 文件中进行替换调用。
module example.com/hello
go 1.16
replace example.com/greetings => ../greetings
英文:
Follow instructions here https://go.dev/doc/tutorial/call-module-code
Mainly you need the replace call in your go.mod file.
module example.com/hello
go 1.16
replace example.com/greetings => ../greetings
答案7
得分: 8
本地包是Go语言中的一个令人讨厌的问题。
对于我们公司的一些项目,我们决定不使用子包。
$ glide install
$ go get
$ go install
这些命令都可以正常工作。
对于一些使用子包的项目,我们使用完整路径导入本地包:
import "xxxx.gitlab.xx/xxgroup/xxproject/xxsubpackage"
但是如果我们fork了这个项目,那么子包仍然引用原始的包。
英文:
Local package is a annoying problem in go.
For some projects in our company we decide not use sub packages at all.
$ glide install
$ go get
$ go install
All work.
For some projects we use sub packages, and import local packages with full path:
import "xxxx.gitlab.xx/xxgroup/xxproject/xxsubpackage
But if we fork this project, then the subpackages still refer the original one.
答案8
得分: 5
根据问题中的描述,文件夹结构如下:
/home/me/go/src/myapp
└─ common
└─ routers
所以进入 myapp 目录:
cd /home/me/go/src/myapp
执行以下命令:
go mod init myapp
这将创建一个 go.mod 文件,让 Go 知道模块的名称为 myapp,这样当它在任何包中查找导入路径时,就知道不要在其他地方查找 myapp。
然后在代码中可以进行以下操作:
import (
"log"
"net/http"
"myapp/common"
"myapp/routers"
)
现在导入了 common 和 routers 包。
英文:
As in the question, the folder structure is:
/home/me/go/src/myapp
└─ common
└─ routers
So go to myapp dir
cd /home/me/go/src/myapp
Do
go mod init myapp
This will create a go.mod file which lets Go know the name of the module myapp so that when it’s looking at import paths in any package, it knows not to look elsewhere for myapp
Then you can do the following in the code:
import (
"log"
"net/http"
"myapp/common"
"myapp/routers"
)
Now package common and routers gets imported.
答案9
得分: 5
另一种方法是使用 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
文件
英文:
Another approach, available since go1.18
, is to use a go.work
file.
First, the local common
package has to be a module, so provide a go.mod
file inside the common
folder:
module common
go 1.18
You can now create a go.work
file in the root of your directory manually or call go work init
, then go work use .
and finally go work use ./common
. It will look like this:
go 1.18
use (
.
./common
)
Finally you can import the package in your code by name
package main
import "common"
Just remember to not commit your go.work
files
答案10
得分: 3
关键是你在以下命令中给模块命名的方式:
go mod init <TheNameGiven>
然后在内部文件夹中引用模块,使用以下方式:
TheNameGiven/folder
我在这里找到了最佳解决方案... 阅读更多
英文:
The key is how you name your module in the following command
go mod init <TheNameGiven>
Then refer the modules in the inner folder with,
TheNameGiven/folder
I have found the best solution here... Read More
答案11
得分: 2
尝试使用"go mod init"命令更改包名。
所以,我有go 1.17,并且遇到了相同的导入问题。我的项目目录是**$GOPATH/src/myswagger/app-swagger-test**。我在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文件。然后我在app-swagger-test目录中运行了以下命令:
go mod init myswagger/app-swagger-test
go mod tidy
之后,项目中的所有导入都成功导入了。在新的go.mod文件中,第一行是:
module myswagger/app-swagger-test
也许这些信息很常见,但我没有找到它。谢谢!
英文:
Try to change the package name with the go mod init command.
So, I have go 1.17, and I have the same import problem. My project directory is $GOPATH/src/myswagger/app-swagger-test. I ran this command into app-swagger-test dir:
go mod init app-swagger-test
go mod tidy
In my new go.mod file the package name is app-swagger-test. For example, this import was wrong:
import (
...
"myswagger/app-swagger-test/internal/generated/restapi"
"myswagger/app-swagger-test/internal/generated/restapi/operations"
)
So I removed go.mod and go.sum. And I ran next commands into app-swagger-test dir:
go mod init myswagger/app-swagger-test
go mod tidy
After that all imports in the project were imported successfully. In the new go.mod file the first line is:
module myswagger/app-swagger-test
Maybe this information is common, but I did not find it. Thanks!
答案12
得分: 0
最小项目结构:
.
├── go.mod
├── main.go
└── utils
└── myUtil.go
main.go
:
package main
import "main/utils"
func main() {
utils.DoSomething()
}
utils/myUtil.go
:
package utils
func DoSomething() {
// 在这里做一些事情
}
go.mod
:
module main
go 1.20
英文:
Minimal project structure:
.
├── go.mod
├── main.go
└── utils
└── myUtil.go
main.go
:
package main
import "main/utils"
func main() {
utils.DoSomething()
}
utils/myUtil.go
:
package utils
func DoSomething() {
// do something here
}
go.mod
:
module main
go 1.20
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论