Это сбивает с толку, и документация предполагает уровень знакомства с Голангом. Я пытался понять Модули недавно. Я надеюсь, что следующее поможет.
С наилучшими пожеланиями, изучая Голанг.
Предыдущий | текущий путь без модулей:
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!
Для полноты
Чтобы показать разницу с внешними пакетами:
No Modules загружает последнюю версию пакета в ${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
, поэтому я использовал это, и условно, файлы названы в соответствии с их содержанием.
- Наши имена каталогов важны. 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
.