Язык программирования Go – для начинающих
- суббота, 1 февраля 2025 г. в 00:00:05
Язык программирования Go, также известный как Golang, был разработан в Google в 2007 году Робертом Гриземером, Робом Пайком и Кеном Томпсоном. Он стал открытым исходным кодом в 2009 году.
Go (или Golang) — это компилируемый, статически типизированный язык программирования, разработанный в Google. Он был создан для упрощения разработки масштабируемых и эффективных программ, особенно в многопоточной среде. Go обладает минималистичным синтаксисом, что делает его легким для изучения и использования. В языке отсутствуют сложные конструкции, такие как наследование и исключения, что также упрощает код.
В этой статье вы узнаете, как написать простое CLI-приложение (интерфейс командной строки) на Go. Сначала мы кратко разберём ключевые особенности языка. Затем обсудим базовую структуру файла в Go. Рассмотрим основные типы данных и конструкции языка.
Скачайте установщик
Перейдите на официальный сайт Go и скачайте файл с расширением .msi
для Windows.
Запустите установщик
Дважды кликните на скачанный файл (например, go1.21.1.windows-amd64.msi
).
Следуйте инструкциям мастера установки (рекомендуется использовать путь по умолчанию C:\Go
).
Проверьте переменную PATH
Установщик автоматически добавляет Go в системную переменную PATH
.
Чтобы проверить, откройте командную строку и выполните:
go version
Если команда не работает, перезагрузите систему или проверьте PATH
вручную:
Панель управления → Система → Дополнительные параметры системы → Переменные среды → Path
.
Скачайте архив
На странице загрузки Go выберите архив для Linux (например, go1.21.1.linux-amd64.tar.gz
).
Распакуйте архив
sudo tar -C /usr/local -xzf go1.21.1.linux-amd64.tar.gz
Добавьте Go в PATH
Откройте файл ~/.profile
или ~/.bashrc
и добавьте строку:
export PATH=$PATH:/usr/local/go/bin
Затем выполните:
source ~/.profile # или source ~/.bashrc
Проверьте установку
go version
Пример вывода: go version go1.21.1 linux/amd64
.
Настройка рабочей директории (опционально)
Создайте папку для проектов и добавьте в ~/.profile
:
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
Скачайте пакет
Загрузите файл .pkg
с официального сайта (например, go1.21.1.darwin-amd64.pkg
).
Запустите установщик
Дважды кликните на файл и следуйте инструкциям (установка в /usr/local/go
).
Проверьте установку
Откройте терминал и выполните:
go version
Установите Homebrew (если не установлен):
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Установите Go
brew install go
Проверьте версию
go version
Далее нужно установить IDE (интегрированную среду разработки) на ваш выбор, если у вас её ещё нет.
Что такое IDE?
Это редактор для написания кода с дополнительными инструментами (отладка, автодополнение и т.д.).
Популярные варианты для Go: Visual Studio Code (VS Code), GoLand, Sublime Text, LiteIDE.
Откройте папку «go-projects» (или как вы ее назвали) с помощью VS Code (или вашего редактора кода на выбор). Создайте папку «hello-go» и создайте файл main.go. Вы можете назвать этот файл как угодно.
Далее напишите классический код с которого многие начинали свой путь в IT.
package main
import "fmt"
func main(){
fmt.Println("Hello, Go!")
}
Ниже разберём что делает этот код.
Объявление пакета (package main): Каждая программа на Go начинается с объявления пакета, указывающего, к какому пакету принадлежит файл. Пакет main
- особый пакет, так как он является точкой входа для исполняемых программ.
Импорт пакета fmt
(import "fmt"): В Go вы импортируете пакеты, чтобы использовать их функции и возможности. Здесь мы импортируем пакет fmt, который означает «формат» и используется для операций ввода и вывода.
Функция main
(func main()): Каждая исполняемая программа на Go должна иметь main
функцию. Когда вы запускаете свою программу, она выполняется первой.
Вывод теста в консоль(fmt.Println(«Hello World»)): В этой строке используется функция Println
из пакета fmt
для печати текста «Hello World» в консоли. Функция Println
используется для печати с символом новой строки в конце, поэтому следующий вывод появляется на новой строке.
Пакеты — это способ организации кода в Go. Пакет представляет собой набор исходных файлов. Он должен быть выполнять одну задачу, например: обработка аргументов, работа с HTTP-запросами и т.д.
Программы запускаются в пакете main
. Пример программы, использующей пакет с путем импорта "fmt"
:
package main
import "fmt"
func main() {
fmt.Println("Hello, Go!")
}
В Go путь импорта — это уникальный идентификатор пакета. Он указывает расположение пакета в системе модулей Go и используется в операторе import
для подключения внешних зависимостей.
Типы пакетов:
Стандартные пакеты
Пакеты из стандартной библиотеки Go подключаются по их имени:
import "fmt"
Удаленные пакеты (из репозиториев)
Go позволяет импортировать пакеты напрямую из репозиториев (GitHub, GitLab и др.):
import "github.com/che1nov/hello-go"
Пакет main
Объявление package main
всегда указывается в начале файла, как показано в примере выше. Функция main()
внутри этого пакета является точкой входа программы.
Модуль — это коллекция пакетов. Он содержит информацию о проекте: зависимости, версию Go, метаданные пакетов. Все проекты на Go имеют файл go.mod
.
Команда для инициализации файла go.mod через терминал:
go mod init <module-path>
Где module-path
соответствует пути импорта пакета.
Команда go
«Команда Go» (go) — это инструмент командной строки в языке программирования Go. Позволяет использовать интсрументы для разработки такие как :
Для запуска кода применяется go run
, который компилирует и сразу выполняет программу.
Чтобы собрать исполняемый файл, используется go build
, преобразующий исходный код в бинарный файл.
Тестирование кода осуществляется через go test
для текущего пакета или go test ./...
для всех поддиректорий.
Управление зависимостями с модулями включает команды: go mod init
для создания нового модуля и файла go.mod
, go get
для загрузки пакетов, go mod tidy
для очистки неиспользуемых зависимостей и go list -m all
для просмотра списка зависимостей.
Документацию можно просматривать через go doc
, указав пакет или элемент.
Анализ зависимостей выполняется с помощью go list
для информации о пакетах и go list -m -versions <module>
для списка версий модуля.
Форматирование кода автоматизирует go fmt
,
Информация о среде Go доступна через go env
.
Эти команды упрощают разработку, сборку, тестирование и поддержку проектов.
Переменная - это именованное значение. Переменные обеспечивают способ хранения и доступа к данным в вашей программе.
Чтобы объявить переменную, вы можете использовать одиночное, составное, создание блока. Давайте рассмотрим примеры каждого из них.
package main
import "fmt"
func main() {
var singleVariable int //обьявление переменной
singleVariable = 10 //присвоение значения 10
fmt.Println(singleVariable)
}
В примере обьявляется переменная singleVariable с явным указанием типа int.
package main
import "fmt"
func main() {
createAndAssignVar := 42 //обьявление и присвоение значения
fmt.Println(createAndAssignVar)
}
Но вы ещё можете создать переменную без явного указания типа данных с помощью :=
, в таком случае тип определится автоматически.
Вы также можете создать несколько переменных одновременно
package main
import "fmt"
func main() {
var a, b, c = 1, 2, "Coders" обьявление и присвоение переменных разных типов
fmt.Println(a, b, c)
}
package main
import "fmt"
func main() {
{
var blockVariable int
blockVariable = 5
fmt.Println(blockVariable)
}
//здесь переменные недоступны
}
Создание блока используется, когда вы хотите ограничить область действия переменных определенным блоком. Вы объявляете и инициализируете несколько переменных в блоке кода {}.
При именовании переменных в Go используется верблюжий регистр(CamelCase). Например:
const myVariable = 20
Когда вы придумываете имя переменной, рекомендуется давать ей описательное имя, например conferenceName := "Linux"
вместо conference := "Linux"
.
В Go есть два способа объявления переменных: var и const. Для тех, кто знаком с JavaScript, это может показаться знакомым.
var
используется для объявления переменных, и их значения могут быть изменены после объявления.
const
используется для объявления констант, и их значения не могут быть изменены после объявления.
Вот пример использования var и const для объявления переменных:
package main
import «fmt»
func main() {
// использование var
var variable1 int = 5
variable1 = 10 // значение variable1 может быть изменено
// Использование const
const constant1 int = 5
constant1 = 10 // ошибка, константы не могут быть переназначены
fmt.Println(variable1, constant1)
}
В приведенном выше примере variable1 может быть переназначена на новое значение, в то время как constant1 не может быть переназначена и выдаст ошибку при компиляции.
В Golang существуют различные типы данных, среди которых числовые, строка, булево значение, массив, указатель, структура, карта и интерфейс.
Давайте рассмотрим примеры каждого из них, чтобы вы могли понимали, как они выглядят.
Число ( int, float64
) используется для представления числовых значений (целых чисел или десятичных дробей). Вот пример:
package main
import "fmt"
func main() {
// целое число
var integerVar int = 42
fmt.Println(integerVar)
// число с плавающей точкой
var floatVar float64 = 3.14
fmt.Println(floatVar)
}
В этом примере integerVar
- это целочисленная переменная, а floatVar
- переменная с плавающей точкой.
Строка(string
)используется для представления последовательности символов.
package main
import "fmt"
func main() {
var stringVar string = "Hello, Go!"
fmt.Println(stringVar)
}
В этом примере stringVar - это строковая переменная, содержащая текст «Hello, Go!».
Тип bool
используется для представления логических значений (true
или false
).
package main
import "fmt"
func main() {
var boolVar bool = true
fmt.Println(boolVar)
}
В этом примере boolVar
- это булева переменная, со значением true
.
Массив(array
) используется для хранения последовательностей элементов фиксированного размера одного типа. Вот пример
package main
import "fmt"
func main() {
var intArray [3]int = [3]int{1, 2, 3}
fmt.Println(intArray)
}
В этом примере intArray
- это массив целых чисел с фиксированным размером 3
.
Указатель(pointer
) используется для хранения адреса переменной в памяти.
package main
import "fmt"
func main() {
var originalVar int = 42 // переменая originalVar со значением 42
var pointerVar *int = &originalVar //указатель на originalVar
fmt.Println(*pointerVar) //разыменование указателя
}
В этом примере pointerVar
- это указатель на адрес памяти originalVar
.
Структура (Struct
) используется для объединения переменных разных типов под одним именем.
package main
import "fmt"
type Person struct { //структура Person с полями Name и Age
Name string
Age int
}
func main() {
var personVar Person = Person{Name: "Alice", Age: 30} // инициализация значений для полей структуры
fmt.Println(personVar)
}
В этом примере personVar
- это структура, представляющая человека с именем и возрастом.
Map
используется для предоставления пар ключ-значение.
package main
import "fmt"
func main() {
var myMap map[string]int = map[string]int{"one": 1, "two": 2, "three": 3}
fmt.Println(myMap)
}
В этом примере myMap
- это карта с ключами типа string
и значениями int
.
Интерфейс(interface
) используется для определения набора сигнатур методов без указания реализации. Уже посложнее. Вот пример с комментариями:
package main
import "fmt"
// Shape объявляет интерфейс для геометрических фигур, способных возвращать свою площадь.
// Любой тип, реализующий метод Area(), удовлетворяет этому интерфейсу.
type Shape interface {
Area() float64
}
// Circle представляет структуру окружности с заданным радиусом.
// Radius хранит значение радиуса окружности в виде числа с плавающей точкой.
type Circle struct {
Radius float64
}
// Area вычисляет площадь окружности по формуле πr².
// Реализует метод интерфейса Shape, позволяя использовать Circle через этот интерфейс.
func (c Circle) Area() float64 {
return 3.14 * c.Radius * c.Radius
}
func main() {
// Создаем экземпляр Circle с радиусом 5.0
circle := Circle{Radius: 5.0}
// Присваиваем Circle переменной типа Shape, демонстрируя полиморфизм.
// Это возможно, так как Circle реализует все методы интерфейса Shape.
var myShape Shape = circle
// Вызываем метод Area() через интерфейсную переменную и выводим результат.
// Вывод: 78.5 (3.14 * 5 * 5)
fmt.Println(myShape.Area())
}
В этом примере Shape
- это интерфейс, а Circle
- тип, реализующий метод Area
интерфейса Shape
.
Теперь давайте пройдемся по каждой категории операторов и посмотрим, как они работают, на примерах.
Арифметические операторы используются, когда вам нужно выполнить основные математические операции в коде. К ним относятся следующие:
package main
import "fmt"
func main() {
a := 15
b := 4
// Арифметические операции
sum := a + b // Сложение
difference := a - b // Вычитание
product := a * b // Умножение
quotient := a / b // Деление (целочисленное)
remainder := a % b // Остаток от деления
// Вывод результатов
fmt.Printf("%d + %d = %d\n", a, b, sum)
fmt.Printf("%d - %d = %d\n", a, b, difference)
fmt.Printf("%d * %d = %d\n", a, b, product)
fmt.Printf("%d / %d = %d (целочисленное деление)\n", a, b, quotient)
fmt.Printf("%d %% %d = %d (остаток)\n", a, b, remainder)
}
Реляционные операторы используются для сравнения значений и принятия решений на основе результатов сравнения. Пример:
package main
import "fmt"
func main() {
a := 15
b := 4
c := 15
d := "apple"
e := "banana"
// Реляционные операторы для чисел
greater := a > b // Больше
less := b < a // Меньше
greaterOrEqual := a >= c // Больше или равно
lessOrEqual := b <= a // Меньше или равно
equal := a == c // Равно
notEqual := a != b // Не равно
// Реляционные операторы для строк (лексикографическое сравнение)
strCompare := d < e
// Вывод результатов
fmt.Printf("Числовые сравнения:\n")
fmt.Printf("%d > %d → %t\n", a, b, greater)
fmt.Printf("%d < %d → %t\n", b, a, less)
fmt.Printf("%d >= %d → %t\n", a, c, greaterOrEqual)
fmt.Printf("%d <= %d → %t\n", b, a, lessOrEqual)
fmt.Printf("%d == %d → %t\n", a, c, equal)
fmt.Printf("%d != %d → %t\n\n", a, b, notEqual)
fmt.Printf("Строковые сравнения:\n")
fmt.Printf("%q < %q → %t (лексикографическое сравнение)\n", d, e, strCompare)
}
Запустим программу, выведет:
Числовые сравнения:
15 > 4 → true
4 < 15 → true
15 >= 15 → true
4 <= 15 → true
15 == 15 → true
15 != 4 → true
Строковые сравнения:
"apple" < "banana" → true (лексикографическое сравнение)
Логические операторы используются, когда вам нужно реализовать логику и принимать решения на основе нескольких условий. Пример:
package main
import "fmt"
func main() {
// Исходные значения для операций
a := true
b := false
c := true
d := false
// Логические операции
andResult := a && b // Логическое И
orResult := b || c // Логическое ИЛИ
notResult := !d // Логическое НЕ
// Комбинированная операция
combined := (a || b) && !(c == d)
// Специфика Go: короткие вычисления (short-circuiting)
shortCircuit := b && someFunc() // someFunc() не будет вызвана
// Вывод результатов
fmt.Printf("Логические операторы:\n")
fmt.Printf("%t && %t → %t\n", a, b, andResult)
fmt.Printf("%t || %t → %t\n", b, c, orResult)
fmt.Printf("!%t → %t\n", d, notResult)
fmt.Printf("(%t || %t) && !(%t == %t) → %t\n", a, b, c, d, combined)
fmt.Printf("Short-circuit: %t (someFunc не вызывалась)\n", shortCircuit)
// Особенность Go: строгая типизация
// x := 1 || 0 // Ошибка: invalid operation
}
// Вспомогательная функция для демонстрации short-circuit
func someFunc() bool {
fmt.Println("Эта функция не должна вызываться!")
return true
}
В этой статье вы узнали о языке программирования Go. Вы узнали о характеристиках Go и о том, как установить Go. Затем вы узнали, как начать писать код на Go, и увидели примеры многих возможностей Go в действии. Мы также поговорили о том, что такое пакеты, как работают модули и многое другое.
Буду рад, если вы поделитесь в комментариях, мнением и советами по изучению языка.
Желаю успехов в дальнейшем изучении!