В чем разница между `go get` и `go install` в Go?
Основное различие между go get и go install
Ключевое различие в том, что go get управляет зависимостями (изменяет go.mod), а go install просто компилирует и устанавливает бинарный файл без изменения файлов модуля.
Исторический контекст и изменения в Go 1.16+
До Go 1.16 команда go get выполняла две функции одновременно:
- Добавляла зависимость в
go.mod - Компилировала и устанавливала бинарник (если пакет был main)
Начиная с Go 1.17 (и особенно с Go 1.18), поведение изменили:
go get— только для управления зависимостями. Он добавляет/обновляет/удаляет строки вgo.modи обновляетgo.sum. Бинарники не устанавливаются.go install— только для установки бинарников. Он компилирует пакет и помещает исполняемый файл в$GOPATH/bin(или$GOBIN).go.modне изменяется.
Пример 1: Установка утилиты (бинарника)
Хотим установить hey для тестирования:
// ПРАВИЛЬНО (Go 1.16+):
go install github.com/rakyll/hey@latest
// НЕПРАВИЛЬНО (устарело):
go get -u github.com/rakyll/hey // В новых версиях Go это не установит бинарник!
После go install бинарник появится в $GOPATH/bin/hey. Команда @latest указывает версию — это обязательный синтаксис для go install.
Пример 2: Добавление библиотеки в проект
Работаем в проекте с go.mod:
// Создаем проект
mkdir myapp && cd myapp
go mod init myapp
// Добавляем зависимость Gin
go get github.com/gin-gonic/gin
// После этого в go.mod появится:
// require github.com/gin-gonic/gin v1.9.1
// А в go.sum — хеши для проверки целостности
// Теперь можно импортировать в коде:
import "github.com/gin-gonic/gin"
Пример 3: Установка бинарника из текущего проекта
// Если в проекте есть cmd/myapp/main.go с package main:
go install ./cmd/myapp
// Бинарник myapp появится в $GOPATH/bin
Обратите внимание: путь указывается относительно текущего модуля, а не полный URL.
Когда что использовать?
go get— когда нужно добавить, обновить или удалить зависимость вgo.modвашего проекта. Например:go get github.com/sirupsen/logrus@v1.9.0go install— когда хотите установить готовую программу (утилиту, CLI-инструмент) из любого репозитория. Например:go install golang.org/x/tools/gopls@latestgo build— когда нужно просто скомпилировать проект без установки бинарника в систему. Например:go build -o myapp .
Важные нюансы
- При использовании
go installс URL (например,go install github.com/user/repo@v1.0.0) Go автоматически загружает модуль во временную директорию, компилирует и помещает бинарник в$GOBIN.go.modвашего текущего проекта не изменяется. - Если вы используете
go installвнутри папки проекта (без URL), то будет скомпилирован текущий модуль. go getбез указания версии (например,go get github.com/package) установит последнюю версию, но с учетом требований других зависимостей вgo.mod.
В итоге: go get — для управления go.mod, go install — для установки бинарников. В новых версиях Go эти функции строго разделены.
Если вам нужно быстро установить инструмент для разработки
Я часто использую такой подход: создаю отдельный модуль для установки утилит, чтобы не засорять рабочие проекты. Например:
// Создаем временную папку
mkdir ~/temp-tools && cd ~/temp-tools
go mod init temp-tools
// Устанавливаем нужные инструменты через go install
go install github.com/rakyll/hey@latest
go install github.com/go-delve/delve/cmd/dlv@latest
go install golang.org/x/tools/gopls@latest
// После установки можно удалить папку temp-tools
cd .. && rm -rf ~/temp-tools
Этот метод гарантирует, что вы не испортите go.mod вашего основного проекта случайными зависимостями. Бинарники при этом останутся в $GOPATH/bin.
Ещё один лайфхак: если вы хотите проверить, куда именно установится бинарник, выполните:
go env GOBIN // если пусто, то используется GOPATH/bin
И не забудьте добавить $GOPATH/bin в переменную окружения PATH, чтобы можно было запускать установленные утилиты из любой папки.
Ответов пока нет.
Войдите чтобы оставить ответ