【问题标题】:How do I use a vendored argument to a function in an external package?如何将 vendored 参数用于外部包中的函数?
【发布时间】:2019-08-05 21:26:44
【问题描述】:

我有包a,它依赖于一个外部包,语言包:

package a

import (
    "fmt"

    "golang.org/x/text/language"
)

// Machine is a printer
type Machine struct{}

// Printer prints
type Printer interface {
    Print(lang language.Tag)
}

// Print prints the language
func (p *Machine) Print(l language.Tag) {
    fmt.Println(l.String())
}

对于包 a,我运行了“dep init”,然后运行了“dep ensure”。

在另一个包中,我有一个 main.go 文件,它导入包 a:

package main

import (
    "testing/a"

    "golang.org/x/text/language"
)

func main() {
    m := a.Machine{}
    m.Print(language.MustParse("en"))
}

我收到一个错误:

cannot use "golang.org/x/text/language".MustParse("en") (type "golang.org/x/text/language".Tag) as type "testing/a/vendor/golang.org/x/text/language".Tag in argument to m.Print

如果我将主包放在包 a 中,它可以正常工作。为什么从外部包调用时不起作用?

Go 版本是 1.10.2

编辑: 我对包 a 有完全的控制权,所以我可以改变我在那里卖东西的方式。如果使用较新的 Go 版本可以轻松修复,我也可以升级我的 Go 版本。

更新: 我已经升级到 Go 1.12.1 并删除了现有的供应商目录。我为包 a 运行了“go mod init”和“go mod vendor”,但在包 b 中运行 main.go 时仍然出现相同的错误。

cannot use "testing/b/vendor/golang.org/x/text/language".MustParse("en") (type "testing/b/vendor/golang.org/x/text/language".Tag) as type "testing/a/vendor/golang.org/x/text/language".Tag in argument to m.Print

如果我尝试直接从我得到的包 a 导入供应商包:

use of vendored package not allowed

【问题讨论】:

  • 你绝对应该升级 Go,因为你落后了 2 个版本并且不再支持它。使用 vendoring 工具确保依赖项被正确展平,或尝试使用 go 模块(go mod vendor 也是创建供应商目录的好方法)
  • 实际上是的,如果您愿意使用这些工具并且没有这些工具,那么扁平化 vendored 依赖可能比直接导入 vendored-dependency-within-a-vendred-dependency 更好潜在的版本冲突。 +1。
  • 我已经为包 a 运行了“go mod init”和“go mod vendor”,但是当我在包 b 中运行 main.go 时仍然出现同样的错误。
  • 顶级项目中的唯一供应商。您可以完全迁移到模块而不用担心供应商,或者使用自动扁平化任何嵌套供应商目录的工具。

标签: go go-modules


【解决方案1】:

如果需要使用依赖项的 vendored 副本,则将标志 -mod=vendor 传递给 go run

例如,

> tree
.
|-- a
|   `-- machine.go
`-- main.go

1 directory, 2 files

创建名为 testing 的模块,因为包 a 在 main 中作为 testing/a 导入

> go mod init testing
go: creating new go.mod: module testing
> go mod vendor #this creates a vendor directory inside the project
go: finding golang.org/x/text/language latest
> tree -L 4
.
|-- a
|   `-- machine.go
|-- go.mod
|-- go.sum
|-- main.go
`-- vendor
    |-- golang.org
    |   `-- x
    |       `-- text
    `-- modules.txt

5 directories, 5 files  
> cat go.mod
module testing

go 1.12

require golang.org/x/text v0.3.0
> go run -mod=vendor main.go
en

上一个答案

下面是我的目录结构:

>tree /F
sample
│---go.mod
│---go.sum
│---main.go
│
└───a
    |---machine.go

Go 版本

> go version
go version go1.12 windows/amd64

模块创建

创建名为 testing 的模块,因为包 a 是 在 main 中导入为 testing/a

> go mod init testing
go: creating new go.mod: module testing

程序执行

> go run main.go
go: finding golang.org/x/text/language latest
en

【讨论】:

  • 任何关于我如何改进答案的评论都会有所帮助。
  • 问题是当依赖项有 vendored 包时类型不匹配。这个答案根本不包括供应商,只是显示了基本的模块用法。这最终可能是正确的过程,但它至少需要解决这个问题,特别是关于为什么模块仍然可以创建相同的情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-08
  • 2021-10-08
  • 1970-01-01
  • 1970-01-01
  • 2019-12-14
  • 1970-01-01
相关资源
最近更新 更多