如何导入本地包没有gopath

我已经使用GOPATH,但对于目前我面临的这个问题,它没有帮助。我希望能够创建特定于项目的包:

myproject/
├── binary1.go
├── binary2.go
├── package1.go
└── package2.go

我尝试了多种方法,但如何让package1.gobinary1.gobinary2.go等工作?

例如;我希望能够import "package1",然后能够运行go build binary1.go,一切正常工作,而不会抛出在GOROOTGOPATH上找不到包的错误。我需要这种功能的原因是大型项目;我不想引用多个其他包或将它们保存在一个大文件中。

305710 次浏览

Go依赖项管理总结:

  • vgo如果你的go版本是:x >= go 1.11
  • depvendor如果你的go版本是:go 1.6 >= x < go 1.11
  • 如果你的go版本是:x < go 1.6,则手动

编辑3:Go 1.11有一个特性vgo,它将取代 dep

要使用vgo,请参阅模块文档。TLDR如下:

export GO111MODULE=on
go mod init
go mod vendor # if you have vendor/ folder, will automatically integrate
go build

这个方法在项目目录中创建一个名为go.mod的文件。然后你可以用go build构建你的项目。如果设置了GO111MODULE=auto,则项目不能在$GOPATH中。


编辑2:自动售货方法仍然有效,没有问题。vendor在很大程度上是一个手动过程,因此创建了depvgo


编辑1:虽然我以前的方法有效,但它不再是“正确”的方法了。你应该使用在Go 1.6中默认启用的供应商功能、vgodep(目前);看到。你基本上是在vendor目录中添加你的“外部”或“依赖”包;编译时,编译器将首先使用这些包。


发现。我可以用GOPATH导入本地包,方法是创建package1的子文件夹,然后用import "./package1"导入binary1.gobinary2.go脚本,如下所示:

binary1.go

...
import (
"./package1"
)
...

所以我的当前目录结构是这样的:

myproject/
├── binary1.go
├── binary2.go
├── package1/
│   └── package1.go
└── package2.go

我还应该注意到相对路径(至少在go 1.5中)也可以工作;例如:

import "../packageX"

没有所谓的“本地套餐”。磁盘上包的组织与包的任何父/子关系是正交的。包形成的唯一真正的层次结构是依赖树,在一般情况下它不反映目录树。

只使用

import "myproject/packageN"

不要无缘无故地反对构建系统。在任何重要的程序中,每次导入都保存十几个字符不是一个好理由,因为,例如,具有相对导入路径的项目是不容易获得的。

导入路径的概念有一些重要的属性:

  • 导入路径可以是全局唯一的。
  • 结合GOPATH,导入路径可以明确地转换为目录路径。
  • GOPATH下的任何目录路径都可以明确地转换为导入路径。

使用相对导入路径会破坏上述所有功能。不要这样做。

PS:在Go编译器测试的遗留代码中,使用相对导入的地方很少。ATM,这是支持相对进口的唯一原因。

也许您正在尝试模块化您的包。我假设package1package2在某种程度上是同一个包的一部分,但为了可读性,你将它们分成多个文件。

如果前面的案例是你的,你可以在这些多个文件中使用相同的包名,就像有相同的文件一样。

这是一个例子:

add.go

package math


func add(n1, n2 int) int {
return n1 + n2
}

subtract.go

package math


func subtract(n1, n2 int) int {
return n1 - n2
}

donothing.go

package math


func donothing(n1, n2 int) int {
s := add(n1, n2)
s = subtract(n1, n2)
return s
}

我不是围棋专家,这是我在stackoverflow的第一个帖子,所以如果你有一些建议,它会很受欢迎。

要向项目中添加“本地”包,请添加一个文件夹(例如“package_name”)。然后把你的实现文件放到那个文件夹里。

src/github.com/GithubUser/myproject/
├── main.go
└───package_name
└── whatever_name1.go
└── whatever_name2.go

在你的package main中这样做:

import "github.com/GithubUser/myproject/package_name"

其中package_name是文件夹名,它必须与whatever_name1文件中使用的包名匹配。Go和whatever_name . Go。换句话说,带有子目录的所有文件应该属于同一个包。

只要在导入中指定父文件夹的整个路径,就可以进一步嵌套更多子目录。

我有一个类似的问题,我目前使用的解决方案使用Go 1.11模块。我有如下结构

- projects
- go.mod
- go.sum
- project1
- main.go
- project2
- main.go
- package1
- lib.go
- package2
- lib.go

我能够从project1和project2导入package1和package2

import (
"projects/package1"
"projects/package2"
)

运行go mod init projects后。我可以从project1和project2目录中使用go build,也可以从projects目录中使用go build -o project1/exe project1/*.go

这种方法的缺点是你所有的项目最终都会在go.mod中共享相同的依赖项列表。我仍在寻找这个问题的解决方案,但它看起来可能是根本性的。

自从go.mod的引入,我认为本地和外部包管理都变得更容易了。使用go.mod,也可以在GOPATH之外创建go项目。

导入本地包:

创建文件夹demoproject,运行以下命令生成go.mod文件

go mod init demoproject

我在demoproject目录中有一个如下所示的项目结构。

├── go.mod
└── src
├── main.go
└── model
└── model.go

出于演示目的,在model.go文件中插入以下代码。

package model


type Employee struct {
Id          int32
FirstName   string
LastName    string
BadgeNumber int32
}


main.go中,我通过引用"demoproject/src/model"导入了Employee模型

package main


import (
"demoproject/src/model"
"fmt"
)


func main() {
fmt.Printf("Main Function")


var employee = model.Employee{
Id:          1,
FirstName:   "First name",
LastName:    "Last Name",
BadgeNumber: 1000,
}
fmt.Printf(employee.FirstName)
}

导入外部依赖:

只需在项目目录中运行go get命令。

例如:

go get -u google.golang.org/grpc

它应该立即包含模块依赖项。国防部文件

module demoproject


go 1.13


require (
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa // indirect
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 // indirect
golang.org/x/text v0.3.2 // indirect
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150 // indirect
google.golang.org/grpc v1.26.0 // indirect
)

https://blog.golang.org/using-go-modules

你可以使用replace

go mod init example.com/my/foo

foo / go.mod

module example.com/my/foo


go 1.14


replace example.com/my/bar => /path/to/bar


require example.com/my/bar v1.0.0

foo / main.go

package main
import "example.com/bar"


func main() {
bar.MyFunc()
}

酒吧/ go.mod

module github.com/my/bar


go 1.14

酒吧/ fn.go

package github.com/my/bar


import "fmt"


func MyFunc() {
fmt.Printf("hello")
}

导入本地包就像导入外部包一样

除了在里面走。Mod文件将外部包名称替换为本地文件夹。

文件夹的路径可以是完整的或相对的/path/to/bar../bar

运行:

go mod init yellow

然后创建一个文件yellow.go:

package yellow


func Mix(s string) string {
return s + "Yellow"
}

然后创建一个文件orange/orange.go:

package main
import "yellow"


func main() {
s := yellow.Mix("Red")
println(s)
}

然后构建:

go build

https://golang.org/doc/code.html

在bash终端中

mkdir <module name>
cd <module name>
go mod init <module name>
touch <module name>.go
  • 在__abc .go中创建go包
cd ..
mkdir main
cd main
go mod init main
touch main.go
  • 创建导入__abc0的主包;
go mod edit -replace=<module name>=<module path>
go mod tidy
  • 看每个go。Mod,如果你想了解go的后台发生了什么 您的文件夹结构将如下所示:
- Project
- <module name>
- <module name>.go
- go.mod
- main
- main.go
- go.mod
go run .

go build &&
./main.exe