我只是发现Go。当我上周开始查看它时,我发现了GOPATH以及Go显然对将代码存储在哪个目录中的态度很坚决。于是我诅咒Google的名字,并确定Go不适合我,然后最近听说了Go模块和他们显然如何解决了这个问题。
问题在于,有关如何构建基于模块的Go项目的在线信息非常匮乏。我在弄清楚如何布置我的代码以及如何调用软件包以使导入正常工作方面遇到困难。我已经尝试了各种方法并查看了示例,但是无论我做什么,都会出现“未知的导入路径”错误。
基本上,我希望有一个包含[]
和main.go
的目录,也许还有一个子目录中的library.go
。我希望能够在library.go
中写import library
或类似的东西,并能够访问main.go
的成员。我还希望能够通过键入library.go
来运行代码。这可以实现吗?
答案 0 :(得分:1)
这令人困惑,并且文档假定您对Golang有所了解。我最近一直在尝试了解Modules。希望以下内容对您有所帮助。
最高兴学习Golang。
WORKDIR=[[PATH-TO-YOUR-WORKING-DIRECTORY]]
mkdir -p ${WORKDIR}/go
export GOPATH=${WORKDIR}/go
export PATH=${GOPATH}/bin:${PATH}
mkdir -p {${WORKDIR}/go/src/foo, ${WORKDIR}/go/src/foo/bar}
然后创建${WORKDIR}/go/src/foo/bar/library.go
:
package bar
func Something() (string) {
return "Hello Freddie"
}
然后创建${WORKDIR}/go/src/foo/main.go
:
package main
import (
"fmt"
"foo/bar"
)
func main() {
fmt.Printf("%s", bar.Something())
}
您将拥有这样的结构:
.
└── go
└── src
└── foo
├── bar
│ └── library.go
└── main.go
然后您可以通过以下两种方式之一来运行它:
GO111MODULE=off go run ${WORKDIR}/go/src/main.go
Hello Freddie!
cd ${WORKDIR}/go/src/
GO111MODULE=off go run main.go
Hello Freddie!
GO111MODULE=off go run foo
Hello Freddie!
假设您已完成上述操作!
您无需执行此步骤,但这是新的最佳实践。我们正在将我们的来源移至${GOPATH}
之外。 ${GOPATH}
仍用于存储我们的版本包。 NB 在这个简单的示例中,我们没有使用外部软件包,因此${GOPATH}
仍然为空。
mv ${WORKDIR}/go/src/foo ${WORKDIR}
rm ${WORKDIR}/go/src
您应使用以下结构:
.
├── foo
│ ├── bar
│ │ └── library.go
│ └── main.go
└── go
NB 我们的消息来源现在不在${GOPATH}
cd ${WORKDIR}/foo
GO111MODULE=on go mod init foo
more go.mod
module foo
go 1.12
GO111MODULE=on go run foo
Hello Freddie!
GO111MODULE=on go run main.go
Hello Freddie!
要显示与外部软件包的区别:
没有模块将软件包的最新版本放入${GOPATH}/src
:
GO111MODULE=off go get github.com/golang/glog
.
├── foo
│ ├── bar
│ │ └── library.go
│ ├── go.mod
│ ├── go.sum
│ └── main.go
└── go
└── src
└── github.com
└── golang
└── glog
├── glog_file.go
├── glog.go
├── glog_test.go
├── LICENSE
└── README
相对于使用模块,将软件包的特定版本(或多个版本)拉入${GOPATH}/pkg
:
GO111MODULE=on go get github.com/golang/glog
.
├── foo
│ ├── bar
│ │ └── library.go
│ ├── go.mod
│ ├── go.sum
│ └── main.go
└── go
└── pkg
├── linux_amd64
│ └── github.com
│ └── golang
│ └── glog.a
└── mod
├── cache
│ ├── download
│ │ └── github.com
│ │ └── golang
│ │ └── glog
└── github.com
└── golang
└── glog@v0.0.0-20160126235308-23def4e6c14b
├── glog_file.go
├── glog.go
├── glog_test.go
├── LICENSE
└── README
library.go
,所以我已经习惯了,按照惯例,文件是根据其内容命名的。library.go
称为freddie.go
或something.go
,也必须将package bar
放在目录bar
中。main.go
通常是在定义func main() {...}
的地方,并且func main() {...}
必须位于称为main
的程序包中。因此,即使目录名为foo
,由于我们想要一个main
函数,我们仍将文件命名为main.go
,并且文件的名称必须为package main
。bar
中,重要的是Something
首先要大写(S
)。这将从bar
包中导出函数,以便其他包可以使用它。如果函数名称为小写(something
),则该函数仅可用于bar
包中的其他函数。