Когда-нибудь хотелось изучить новый язык программирования? Go - отличный выбор!

Недавно я услышал много шума о программировании на Go, и это вызвало у меня любопытство. Сторонники Go хвалят его простоту, параллелизм и производительность - поскольку последние несколько лет я в основном был программистом только на Python, поэтому я хотел попробовать начать с Go сам. Изучив некоторые основы, я обнаружил, что проще всего попытаться найти прямые соответствия между Python и эквивалентной операцией в Go. Вот лишь небольшое введение, чтобы начать работу с Go самостоятельно.

Установка

Чтобы установить Go (или golang), вы можете либо посетить их сайт, либо использовать Homebrew, где это очень просто:

brew install go

Это было просто! Напишем нашу первую программу на Go.

Настройка нашей программы Go

Начнем с базового шаблона для наших программ Go. Мы можем создать папку с именем go_tutorial, в которой будет находиться весь наш код. Начнем с создания файла с именем main.go для нашего первого фрагмента кода. Вверху нашего файла находится определение пакета. Поскольку Go скомпилирован, точка входа для нашей программы будет в функции main() пакета main. Итак, у нас будет что-то вроде этого:

// main package
package main
// main() function
func main() {
}

Еще нам понадобится импорт пакетов. Например, чтобы вывести текст на экран терминала (как мы это сделаем в первом примере), мы должны импортировать пакет с именем fmt. После добавления импорта пакетов наш код будет выглядеть так:

// main package
package main
// package imports
import "fmt"
// main() function
func main() {
}

Компиляция и запуск нашей программы

Для запуска нашей программы у нас есть несколько вариантов. Поскольку Go - это скомпилированный язык, перед запуском нашей программы есть этап компиляции. Если мы хотим, чтобы оба этих шага выполнялись одной командой, мы можем использовать go run:

> go run main.go

Конечно, мы ничего не получим, поскольку наша функция main() в настоящее время пуста. Другой метод запуска нашей программы - использовать go build для создания двоичного файла, который мы затем можем выполнить. Если мы предоставим go build без имени файла, наш двоичный файл будет именем всего пакета, который в нашем случае go_tutorial. Если мы передадим имя файла main.go в go build, мы получим двоичный файл с именем main:

# With no filename
> go build
> ./go_tutorial
# With filename
> go build main.go
> ./main

Обратите внимание, что запуск go run пропускает этап сохранения двоичного файла и запускает программу напрямую.

Хорошо, приступим к написанию наших программ!

Печать текста

Чтобы вывести текст на экран, мы используем функцию из пакета fmt под названием Println(). Обратите внимание, что функция имеет первую букву с заглавной буквы - в Go функции, предоставляемые из пакетов (называемые экспортируемыми функциями), должны начинаться с заглавной буквы.

package main
import "fmt"
func main() {
  fmt.Println("Go!")
}

Запустим нашу программу:

> go build
> ./go_tutorial
Go!

Объявления переменных

В отличие от Python, Go является языком со статической типизацией, поэтому переменные должны быть явно объявлены. Например, чтобы объявить переменную a с целым типом, мы используем следующее:

var a int 

Переменная a теперь имеет целочисленный тип. Если мы попытаемся переназначить его другому типу переменной, мы получим ошибку во время компиляции:

func main() {
  var a int
  a = 5
  fmt.Println(a)
  a = "hi"
}
> go run main.go
# command-line-arguments
./main.go:9:4: cannot use "hi" (type untyped string) as type int in assignment

Когда мы пытались переназначить a с 5 на hi, мы получаем ошибку во время компиляции, в которой говорится, что мы не можем использовать строку как целое число.

Мы также можем сделать объявление и присвоение переменной в одной строке, и Go определит тип:

func main() {
  var a = "Go!"
  fmt.Println(a)
}
> go run main.go
Go!

Теперь есть еще более короткий способ сделать это - мы можем использовать оператор :=, чтобы также выполнять объявление и присваивание в одной строке.

func main() {
  var a := "Go!"
  fmt.Println(a)
}
> go run main.go
Go!

Списки

Структура данных, наиболее похожая на списки Python в Go, - это срез. Срезы в Go - это абстракция от типа данных массива, позволяющая использовать более полезные функции управления. Мы можем создать пустой целочисленный срез следующим образом:

func main() {
  var list []int
  fmt.Println(list)
}
> go run main.go
[]

Мы можем инициализировать наш срез с помощью оператора := - кроме того, мы можем индексировать наши срезы точно так же, как в Python.

func main() {
  list := []int{1, 2, 3, 4, 5}
  fmt.Println(list)
  fmt.Println(list[2])
}
> go run main.go
[1, 2, 3, 4, 5]
3

Как и в случае со списками Python, мы можем добавлять элементы к нашим фрагментам:

func main() {
  list := []int{1, 2, 3}
  fmt.Println(list)
  list = append(a, 100, 200)
  fmt.Println(list)
}
> go run main.go
[1, 2, 3]
[1, 2, 3, 100, 200]

Словари

Чтобы добиться аналогичного поведения со словарями Python, мы можем использовать Go maps, которые представляют собой структуры данных, которые также отображают пары ключ-значение. Объявление map имеет форму map[key type]value type, поэтому для создания пустой карты с ключами типа string и значениями типа int мы используем следующее:

func main() {
  dictionary := map[string]int{}
  fmt.Println(dictionary)
}
> go run main.go
map[]

Добавление пар ключ-значение на нашу карту точно так же, как в Python

func main() {
  dictionary := map[string]int{}
  dictionary["a"] = 1
  dictionary["b"] = 2
  dictionary["z"] = 26
  fmt.Println(dictionary)
  fmt.Println(dictionary["b"])
}
> go run main.go
map[a:1 b:2 z:26]
2

Циклы

В Go есть только один цикл - цикл for. Мы можем адаптировать синтаксис цикла for, чтобы он вел себя как другие конструкции цикла в Python, например, while циклы.

Чтобы создать цикл for с указанным количеством итераций:

func main() {
  for i := 1; i <= 5; i++ {
    fmt.Println(i)
  }
}
> go run main.go
1
2
3
4
5

Чтобы выполнить цикл до тех пор, пока условие не будет выполнено (например, цикл while), мы делаем следующее, где i++ - операция приращения, как i += 1 в Python.

func main() {
  i := 1
  for i <= 5 {
    fmt.Println(i)
    i++
  }
}
> go run main.go
1
2
3
4
5

Наконец, если мы хотим создать бесконечный цикл до тех пор, пока не будет выполнено условие (например, while True), мы можем сделать следующее:

func main() {
  for {
    fmt.Println("Infinite Loop!")
    break
  }
  fmt.Println("Loop ended")
}
> go run main.go
Infinite Loop!
Loop ended

Условная логика

Операторы if / else работают в Go практически так же, как и в Python, за исключением того, что в Python явно используется else if вместо elif.

func main() {
  for i := 1; i <= 10; i++ {
    if i % 2 == 0 {
      fmt.Println("Even")
    } else {
      fmt.Println("Odd")
    }
  }
}
> go run main.go
Odd
Even
Odd
Even
Odd
Even
Odd
Even
Odd
Even

Функции

Наконец, мы можем объявлять функции и использовать их в нашей main() функции. Это работает очень похоже на функции в Python, но поскольку Go статически типизирован, вы должны объявить типы ввода и возврата вашей функции, например:

func myFunction (variableName type) returnType

Итак, если бы мы написали функцию для вычисления факториала числа, мы могли бы сделать следующее. Мы также можем вызвать нашу факториальную функцию из main():

func main() {
  fmt.Println(factorial(3))
  fmt.Println(factorial(6))
}
func factorial(n int) int {
  if n < 2 {
    return 1
  }
  out := 1
  for n > 0 {
    out *= n
    n--
  }
  return out
}
> go run main.go
6
720

Заключительные замечания

Надеюсь, вам понравилась эта статья, и этого было достаточно, чтобы вы начали свое путешествие по Go! Один из моих любимых ресурсов - На примерах - здесь мы коснулись лишь поверхности, но вы можете узнать о некоторых других нюансах языка, перейдя туда.

Вы можете увидеть некоторые из моих работ на моей личной странице GitHub. Я ценю любую обратную связь, и вы можете найти меня в Твиттере и связаться со мной в LinkedIn, чтобы получать больше обновлений и статей.