我应该如何构造Go模块,以便能够轻松运行它并导入内部包?

我应该如何构造Go模块,以便能够轻松运行它并导入内部包?,go,Go,我只是去看看。当我上周开始研究它时,我发现GOPATH和how Go显然对您存储代码的目录非常固执己见。所以我诅咒谷歌的名字,认为Go不适合我,然后最近听说了Go模块,以及它们是如何解决这个问题的 问题在于,关于如何构建基于模块的Go项目的在线信息似乎非常缺乏。我很难弄清楚如何布局我的代码,以及如何调用包以使导入工作。我尝试了各种方法并查看了示例,但无论我做什么,都会出现“未知导入路径”错误 基本上,我希望有一个目录,比如说,main.go和library.go,可能在子目录中有library.

我只是去看看。当我上周开始研究它时,我发现GOPATH和how Go显然对您存储代码的目录非常固执己见。所以我诅咒谷歌的名字,认为Go不适合我,然后最近听说了Go模块,以及它们是如何解决这个问题的

问题在于,关于如何构建基于模块的Go项目的在线信息似乎非常缺乏。我很难弄清楚如何布局我的代码,以及如何调用包以使导入工作。我尝试了各种方法并查看了示例,但无论我做什么,都会出现“未知导入路径”错误


基本上,我希望有一个目录,比如说,
main.go
library.go
,可能在子目录中有
library.go
。我希望能够在
main.go
中编写
import library
或类似内容,并能够访问
library.go的成员。我还希望能够通过键入
go run main.go
来运行代码。这是可以实现的吗?

这令人困惑,文档假定对Golang有一定程度的熟悉。我最近一直在努力理解模块

前一种|当前无模块方式:
WORKDIR=[[PATH-TO-YOUR-WORKING-DIRECTORY]]
mkdir-p${WORKDIR}/go
导出GOPATH=${WORKDIR}/go
导出路径=${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"
}
package main

import (
    "fmt"
    "foo/bar"
)

func main() {
    fmt.Printf("%s", bar.Something())
}
然后创建
${WORKDIR}/go/src/foo/main.go

package bar

func Something() (string) {
    return "Hello Freddie"
}
package main

import (
    "fmt"
    "foo/bar"
)

func main() {
    fmt.Printf("%s", bar.Something())
}
您将拥有如下结构:

.
└── go
    └── src
        └── foo
            ├── bar
            │   └── library.go
            └── main.go
.
├── foo
│   ├── bar
│   │   └── library.go
│   └── main.go
└── go
然后,您可以通过以下任一方式运行此操作:

GO111MODULE=off go run${WORKDIR}/go/src/main.go
你好,弗雷迪!
cd${WORKDIR}/go/src/
GO111模块=关闭运行运行main.go
你好,弗雷迪!
GO111MODULE=关闭运行foo
你好,弗雷迪!
模块的新(!)方式: 假设你已经做了以上的事情

您不需要执行此步骤,但这是新的最佳实践。我们正在将源代码移到
${GOPATH}
之外<代码>${GOPATH}
仍然用于存储我们的版本包NB在这个简单的示例中,我们没有使用外部包,因此
${GOPATH}
保持为空

mv${WORKDIR}/go/src/foo${WORKDIR}
rm${WORKDIR}/go/src
您应该创建这样的结构:

.
└── go
    └── src
        └── foo
            ├── bar
            │   └── library.go
            └── main.go
.
├── foo
│   ├── bar
│   │   └── library.go
│   └── main.go
└── go
NB我们的来源现在在
${GOPATH}

cd${WORKDIR}/foo
GO111MODULE=on go mod init foo
更多go.mod
模块foo
加油1.12
GO111模块=运行中的foo
你好,弗雷迪!
GO111模块=运行中运行main.go
你好,弗雷迪!
为了完整性 要显示与外部软件包的差异,请执行以下操作:

没有模块将包的最新版本拉入
${GOPATH}/src

GO111MODULE=off go get github.com/golang/glog
.
├── 福
│   ├── 酒吧
│   │   └── 去图书馆
│   ├── go.mod
│   ├── 加油
│   └── 梅因,加油
└── 去
└── src
└── github.com
└── 戈兰
└── 格洛格
├── glog_file.go
├── 格洛格·戈
├── 格洛古测试
├── 许可证
└── 自述
与使用模块相比,将包的特定版本拉入
${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
    ,所以我使用了它,按照惯例,文件是以其内容命名的
  • 我们的目录名很重要。Go使用目录名帮助查找包。因此,即使
    library.go
    可以被称为
    freddie.go
    something.go
    ,重要的是它应该是
    package bar
    并位于名为
    bar
    的目录中
  • 这些规则的一个例外是
    main.go
    通常在定义
    func main(){…}
    的地方,并且
    func main(){…}
    必须位于名为
    main
    的包中。因此,即使目录名为
    foo
    ,因为我们需要
    main
    函数,我们将文件命名为
    main.go
    ,它必须是
    package main
  • 在package
    bar
    中,重要的是
    某物的首字母大写(
    s
    )。这将从
    包导出函数,以便其他包可以使用它。如果函数名为小写(
    something
    ),则该函数仅对
    bar
    包中的其他函数可用

这不仅是可以实现的,也是典型围棋项目的定义。以模块为例,看看任何Go项目。没有“最佳方式”来组织项目。如果您有特定的问题,请发布该问题并包含相关代码。@Adrian我的问题是我不知道从哪里开始,也找不到任何示例代码。只讨论外部依赖关系。似乎建议,如果我只使用cmd/internal样式的目录结构,然后键入
go-run[my-main file]
,它应该可以工作,但不起作用。同时,谷歌搜索这些问题会导致许多论坛帖子,人们抱怨这很难做到,并建议解决方法,包括
replace
。我没有具体的问题和示例代码,因为我是初学者,不知道自己在做什么。我当然试过很多东西,但我不打算在这里发布10个
。go
文件价值的死胡同,只是为了证明我试过了。我所需要的只是一个简单的两个文件示例项目,就像我建议的那样,包括目录结构和要使用的
go-run
命令。谢谢,我能够复制您的工作