【问题标题】:Accessing local packages within a go module (go 1.11)在 go 模块中访问本地包(go 1.11)
【发布时间】:2019-02-01 05:20:56
【问题描述】:

我正在试用 Go 的新模块系统,但无法访问本地包。以下项目位于我的 gopath 之外的桌面上的一个文件夹中。

我的项目结构如下:

/
  - /platform
      - platform.go
  - main.go
  - go.mod

// platform.go
package platform

import "fmt"

func Print() {
    fmt.Println("Hi")
}

// main.go
package main

import "platform"

func main() {
    platform.Print()
}

go build main.go 告诉我

cannot find module for path platform

【问题讨论】:

  • 嗨,大卫,如果您认为我的回答回答了您的问题,请考虑将其标记为答案。谢谢!
  • 从 2.3.3 开始的 maven golang 插件还允许使用本地模块(它在构建过程中自动添加本地路径),您可以查看一些示例 github.com/raydac/mvn-golang/tree/master/mvn-golang-examples/…

标签: go vgo


【解决方案1】:

让我首先定义modulespackages 的集合。在 Go 11 中,我使用 go modules,如下所示:

如果两个包都在同一个项目中,您可以执行以下操作: 在go.mod

module github.com/userName/moduleName

在你的main.go里面

import "github.com/userName/moduleName/platform"

但是,如果它们是单独的模块,即不同的物理路径,并且您仍想导入本地 packages 而不将其远程发布到 github,例如,您可以通过使用 replace 指令来实现。

给定模块名称 github.com/otherModuleplatform,正如您所说的那样,是其中唯一的包。在主模块的go.mod 中添加以下行:

module github.com/userName/mainModule

require "github.com/userName/otherModule" v0.0.0
replace "github.com/userName/otherModule" v0.0.0 => "local physical path to the otherModule"

注意:路径要指向模块的根目录,可以是绝对的,也可以是相对的。

main.go 内部,从otherModule 导入特定的包,如platform

import "github.com/userName/otherModule/platform"

这是 Golang 模块的gentle introduction

【讨论】:

  • 天啊,这个答案对我帮助很大。谢谢:)
  • 我使用了只包含 replace 指令的 go.mod,构建项目不需要 require 指令。
  • 我的问题是为什么模块必须有 github.com...问题是关于本地文件,为什么必须回答包含一个 url?那是我的问题...很难像其他编程语言一样使用文件路径吗?还是我们必须将所有内容都视为外部 url?
  • @uberrebu 在最新版本的 Go(在 1.15 中测试)中不再需要点或 FQDN。在excellent howtothe overview 部分阅读更多相关信息。
【解决方案2】:

我强烈建议您使用开箱即用的 go 工具链来解决这些问题。带有 vscode-go 插件的 Visual Studio Code 真的很有用。

这里的问题是 Go 在 import 语句中需要相对于您的 $GOPATH/srcmodule 的相对路径。根据您在GOPATH 中的位置,导入路径也应该包含它。在这种情况下,import语句必须在go.mod中包含go模块路径

GOPATH

假设您的项目位于此处:

$GOPATH/src/github.com/myuser/myproject

您的导入路径应该是:

import "github.com/myuser/myproject/platform"

VGO

假设你的 go.mod 文件是:

module example.com/myuser/myproject

您的导入路径应该是:

import "example.com/myuser/myproject/platform"

【讨论】:

  • 等等,我很困惑。如果我的模块只是在我的文件系统的某个地方,模块系统如何找到它?
  • 如果您在一个模块中,它会使用包导入路径和磁盘上go.mod 文件的位置在同一模块中查找包,只要导入路径是完整的导入路径从模块名称开始(例如,import "github.com/my/module/pkg"`)。如果您想在磁盘上其他位置的其他模块中查找包,那么这就是replace 指令的用武之地。这个answer 涵盖了更多关于模块结构和导入路径。
  • 为什么每个人都继续使用 url 格式?问题很明确:localmodule/localmodule.go 就是这样。为什么这里有 githubs 和 example.com?
  • @holms 答案和您上面的评论对此进行了解释,但需要澄清的是,该语言没有定位内部包的机制,只有 go 工具可以。 go 工具依赖于 GOPATH 或模块配置 (go.mod)。本质上,您正在使用 go 工具将本地包与 任何其他类型的包 一样处理。另请参阅有关此问题的其他一些答案。
  • 我的问题是为什么模块必须有github.com...问题是关于本地文件,为什么必须回答包含一个url???那是我的问题...很难像其他编程语言一样使用文件路径吗?还是我们必须将所有内容都视为外部 url?
【解决方案3】:

作为一个新人,我并没有立即理解接受的答案——顺便说一句,这很好。对于那些非常新的人,这里有一个简短的答案!

在 go 模块/包中表示为您在代码中导入的 url:

import your.org/internal/fancy_module

等一下!我的代码不在网址上,这是怎么回事??

这就是围棋的聪明之处。你假装有一个url,即使没有。因为:

  1. 这使得包含更容易,因为无论您的文件位于何处,导入都使用相同的 url(即使文件移动,代码也保持不变!)
  2. 您的包可能存在命名冲突。所以google.com/go-api/useryour.org/internal/user 的定义不冲突
  3. 有一天你可能会在 GitHub 上发布一个 url,所有代码都可以正常工作

Evan 太棒了,但是如何导入相对路径?

好问题!您可以通过将 go.mod 文件更改为具有此行来导入:

module fancy_module

go 1.16

replace your.org/fancy_module => ../path/to/fancy_module

【讨论】:

  • 你是我的救星!我知道不鼓励“替换”只是因为它是不好的做法,但这正是我需要挽救一个有点过时的项目。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-21
  • 1970-01-01
  • 2019-06-21
  • 1970-01-01
  • 2022-12-22
  • 2019-10-06
  • 1970-01-01
相关资源
最近更新 更多