英文:
Locally importing package
问题
我有一个名为foo
的包,它位于名为utils
的子目录中。当我尝试在main.go
中导入它时,找不到它。不确定我做错了什么。
运行go build
时出现错误:
错误:
main.go:7:2: 非本地包中的本地导入"./utils/csrf"
所以我的文件夹结构如下:
github.com/project
/utils
foo.go
main.go
该包的代码如下:
package foo
import (
"fmt"
)
func Bar() {
fmt.Printf("function")
}
Go Mod文件如下:
module github.com/project
go 1.15
我在main.go
文件中尝试这样导入它:
import (
"fmt"
"github.com/project/utils/foo"
)
英文:
I have a package I want to break out my code with called foo
and it's in a subdirectory called utils
. When I try to import it to my main.go it can't find it. Not sure what I'm doing wrong.
Error when running go build
Error:
main.go:7:2: local import "./utils/csrf" in non-local package
So I have folder structured as:
github.com/project
/utils
foo.go
main.go
The package is written as so:
package foo
import (
"fmt"
)
func Bar() {
fmt.Printf("function")
}
Go Mod:
module github.com/project
go 1.15
And I'm trying to import is as so in my main.go
file.
import (
"fmt"
"github.com/project/utils/foo"
)
答案1
得分: 2
首先,在某个地方创建一个名为utils
的文件夹。你不需要创建任何github.com/project
文件夹,只需简单地创建一个utils
文件夹,并将其放在硬盘的某个位置。然后进入该文件夹,执行go mod init github.com/project/utils
命令。然后创建utils/foo.go
文件:
package utils
import "fmt"
func Bar() {
fmt.Println("function")
}
然后创建一个名为utils/utils
的文件夹。在该文件夹中创建一个文件utils/utils/main.go
:
package main
import "github.com/project/utils"
func main() {
utils.Bar()
}
然后执行go build
命令。完成。
英文:
First, make a folder utils
somewhere. You don't need to do any
github.com/project
folder. Just simply make a utils
folder, and put it somewhere on your hard drive. Then go into that folder, and do go mod init github.com/project/utils
. Then make utils/foo.go
:
package utils
import "fmt"
func Bar() {
fmt.Println("function")
}
Then make a folder utils/utils
. Then make a file utils/utils/main.go
:
package main
import "github.com/project/utils"
func main() {
utils.Bar()
}
Then do go build
. Done.
答案2
得分: 1
错误信息 main.go:7:2: local import "./utils/csrf" in non-local package
来自这里。除非有意外的错误,这意味着你的 main.go
不是像你描述的那样:
import (
"fmt"
"github.com/project/utils/foo"
)
而更像是这样:
import (
"fmt"
"./utils/foo"
)
然而,在模块模式下不能在 import
语句中使用相对导入路径(relative import paths)(关于模块模式下的实际错误信息由于 go
命令中的一个错误而有些混乱,我已经提交了一个问题报告:https://golang.org/issue/47088)。
在模块模式下,go.mod
文件中声明的模块路径(对于你的示例可能是 module github.com/project
)是导入路径的前缀,你应该在 import
语句中使用完整路径。
因此,解决方案可能是:
- 进入
project
文件夹。 - 运行
go mod init github.com/project
。 - 在整个项目中,将
import
语句中的相对路径改为完整路径:$ sed -i 's,"\./utils,"github.com/project/utils,' $(find -name *.go)
这将使你的 main.go
实际上变为:
import (
"fmt"
"github.com/project/utils/foo"
)
但现在还有一个步骤:Go 只支持每个目录一个包,并且在 .go
源文件中使用 package
指令声明的包名(可能令人困惑!)_不是_包导入路径的后缀,它是完全独立的。
因此,为了使那个 import
语句起作用,你需要额外的目录结构层次:
mkdir utils/foo
mv utils/foo.go utils/foo/foo.go
现在你有一个单一模块 github.com/project
,包含两个包:github.com/project
,其源文件为 ./main.go
,以及 github.com/project/utils/foo
,其源文件为 ./utils/foo/foo.go
。
英文:
The error message main.go:7:2: local import "./utils/csrf" in non-local package
comes from here. Barring an unexpected bug, it would imply that your main.go
does not look like:
import (
"fmt"
"github.com/project/utils/foo"
)
as you described, but, rather, something more like:
import (
"fmt"
"./utils/foo"
)
However, relative import paths cannot be used in import
statements in module mode. (The actual error message you get in module mode is somewhat confusing due to a bug in the go
command, for which I've filed <https://golang.org/issue/47088>.)
In module mode, the module path declared in the go.mod
file — presumably module github.com/project
for your example — is a prefix of the import path, and you are intended to use the complete path in import
statements.
So the solution here is likely:
cd
to theproject
folder.- Run
go mod init github.com/project
. - Change the
import
statements to use the full path instead of the relative one throughout the project:$ sed -i 's,"\./utils,"github.com/project/utils,' $(find -name *.go)
That should change your main.go
to actually read:
import (
"fmt"
"github.com/project/utils/foo"
)
But now there is one more step: Go supports only one package per directory, and the package name declared with the package
directive in the .go
source file is (perhaps confusingly!) not a suffix of the package import path — it is completely independent.
So in order to make that import
statement work, you need an extra layer of directory structure:
mkdir utils/foo
mv utils/foo.go utils/foo/foo.go
Now you have a single module, github.com/project
, containing two packages: github.com/project
with source file ./main.go
, and github.com/project/utils/foo
with source file ./utils/foo/foo.go
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论