本地导入包

huangapple go评论70阅读模式
英文:

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 语句中使用完整路径。

因此,解决方案可能是:

  1. 进入 project 文件夹。
  2. 运行 go mod init github.com/project
  3. 在整个项目中,将 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 语句起作用,你需要额外的目录结构层次:

  1. mkdir utils/foo
  2. 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:

  1. cd to the project folder.
  2. Run go mod init github.com/project.
  3. Change the import statements to use the full path instead of the relative one throughout the project:
    $ sed -i &#39;s,&quot;\./utils,&quot;github.com/project/utils,&#39; $(find -name *.go)
    

That should change your main.go to actually read:

import (
  &quot;fmt&quot;
  &quot;github.com/project/utils/foo&quot;
)

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:

  1. mkdir utils/foo
  2. 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.

huangapple
  • 本文由 发表于 2021年7月6日 03:11:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/68261085.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定