【问题标题】:Go: local import in non-local packageGo:非本地包中的本地导入
【发布时间】:2015-09-02 07:20:08
【问题描述】:

我的文件结构如下:

.
├── bin
│   └── hello
├── pkg
└── src
    └── jacob.uk.com
        ├── greeting
        │   └── greeting.go
        └── helloworld.go

5 directories, 3 files

使用以下 GOPATH

/Users/clarkj84/Desktop/LearningGo

src 文件夹中执行/usr/local/go/bin/go install jacob.uk.com 时,我收到错误local import "./greeting" in non-local package

helloworld.go:

package main;
import "./greeting"

func main() {

}

【问题讨论】:

    标签: go


    【解决方案1】:

    将非本地包指定到go install 时,您不能使用本地导入。如果您希望本地导入工作,首先将工作目录更改为src/jacob.uk.com,然后执行go install(不指定包)。

    当然有你提供的helloworld.go,你会得到一个编译错误:imported and not used。但是一旦你使用了导入的 greeting 包中的东西,它应该可以编译。

    但您根本不应该使用本地导入。而是写:

    import "jacob.uk.com/greeting"
    

    这样做您将能够从任何地方编译/运行/安装它。

    【讨论】:

    • 这给我一个找不到包错误。 go-contacts 是主文件夹,子文件夹中的应用程序,在 main.go "go-contacts/app"
    • @icza 我不确定你的 URL 路径是什么意思。我在 mypkg/mypkg.go 中有包,如何在 main.go 中导入它?
    • 对我不起作用。如果我这样做,我会得到未定义:问候。
    • @oopexpert 包名是greeting 不是greetings
    • @oopexpert 然后在新问题中发布minimal reproducible example。我不知道你有什么。你现在必须使用 go 模块。
    【解决方案2】:

    键入 go build 不适用于相对导入路径;你必须输入go build main.go

    go install 根本不适用于相对导入路径。

    记录在https://golang.org/cmd/go/#hdr-Relative_import_paths

    解释。

    【讨论】:

      【解决方案3】:

      您可以在 go 1.11 中使用替换添加本地包

      module github.com/yourAccount/yourModule
      
      go 1.15
      
      require (
          github.com/cosmtrek/air v1.21.2 // indirect
          github.com/creack/pty v1.1.11 // indirect
          github.com/fatih/color v1.9.0 // indirect
          github.com/imdario/mergo v0.3.11 // indirect
          github.com/julienschmidt/httprouter v1.3.0
          github.com/mattn/go-colorable v0.1.7 // indirect
          github.com/pelletier/go-toml v1.8.0 // indirect
          go.uber.org/zap v1.15.0
          golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a // indirect
      )
      
      replace (
          github.com/yourAccount/yourModule/localFolder =>"./yourModule/localFolder"
          github.com/yourAccount/yourModule/localFolder =>"./yourModule/localFolder"
      )
      

      然后在你的 main.go =>

      import (
          alog "github.com/yourAccount/yourModule/localFolder"
          slog "github.com/yourAccount/yourModule/localFolder"
      )
      

      【讨论】:

      • 我不确定为什么这个答案被否决,因为这个确切的解决方案已经解决了我遇到的问题(在我完成开发之前,我的包不会合并到源代码控制的根分支中在他们)。有人可以建议这是否是处理这种情况的“坏”方式吗?
      • 替换指令的路径参数不需要引用。在 go1.16 上测试。
      • 实际上是转到您的 (go workspace) -> go/src 文件夹并在那里创建项目的最佳方式。这只是一种解决方法。
      【解决方案4】:

      您可以使用供应商功能绕过此问题
      import "./greeting" 更改为 import "greeting"
      创建供应商目录mkdir vendor 并创建符号链接ln -s ../greeting vendor/greeting

      【讨论】:

      • 不错。谢谢 - 鼓励我阅读供应商目录。尽管我可能会切换到 dep 工具,但手动执行此操作有助于我理解。
      【解决方案5】:

      可能有几件事情出错了。我将提供以下设置。

      检查您的 GOPATH 环境变量

      GOPATH 变量定义您的工作区。如果您输入“go env”,您可以轻松识别当前值。

      如果您在 Windows 下安装 Go,GOPATH 环境变量会在安装过程中自动设置。尽管如此:这个默认路径可能不是您的首选。您可以安全地将此变量设置为您希望的目标目录。

      要更改 Windows 中的环境变量,请查看此处:https://www.architectryan.com/2018/08/31/how-to-change-environment-variables-on-windows-10/

      检查工作区布局

      如果您已经决定了工作区的位置并设置了 GOPATH 环境变量,您应该在工作区中创建三个文件夹:

      src、pkg、bin

      文件夹“src”是您的源代码所在的位置。 “pkg”包括外部进口。 "bin" 包含已编译的源代码。

      示例项目

      在您的工作区中布局:

      <workspace directory>
      --> src
          --> oopexpertutil
              --> x.go
          --> y.go
      --> pkg
          --> ...
      --> bin
          --> ...
      

      文件“x.go”

      package oopexpertutil
      
      func checkMe(e error) {
          if e != nil {
              panic(e)
          }
      }
      

      文件“y.go”

      package main
      
      import (
          "fmt"
          "io/ioutil"
          "oopexpertutil"
      )
      
      func main() {
      
          var data string = "Hello World!"
          var dataAsBytes = []byte(data)
      
          fmt.Println(data)
      
          err := ioutil.WriteFile("hello_world.txt", dataAsBytes, 0644)
      
          fmt.Println(err)
      
          oopexpertutil.checkMe(err)
      
      }
      

      失望...

      此设置仍然无效。您可能已经尝试过所有其他坚持工作区或包布局或“go modules”主题的答案。完成这项工作需要考虑的最后一点是:

      将引用包的“checkMe”函数名称改为“CheckMe”并更新用法...

      Go 有一些约定,可以从 未导出的函数 中识别 导出的函数 以大写字母开头

      【讨论】:

        【解决方案6】:

        如果您只想在单独的文件而不是单独的包之间共享代码,请执行以下操作:

        你不需要import,你只需要把源文件放在同一个目录下,并在每个文件的顶部指定相同的package名称,然后你就可以访问所有公共(大写) 函数和类型,通过直接引用它们,即SomeFunction() 而不是somepackage.SomeFunction()

        【讨论】:

          猜你喜欢
          • 2016-05-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-07-29
          • 1970-01-01
          • 1970-01-01
          • 2021-09-16
          • 1970-01-01
          相关资源
          最近更新 更多