Go: или как я снова полюбил статические типы

Сверхпростое введение, показывающее, как Go возвращает современную сеть C-суперсилы с синтаксическими поворотами многих привлекательных языков сценариев.

На прошлой неделе, после месяца изучения Arduino / C ++ и Javascript программирования микроконтроллера Spark и веб-приложения Socket.io для моего недавнего игрушечного проекта IoT, я решил убить свое время, опробуя Go , новый язык, разработанный Google из любопытства, чтобы узнать, о чем идет речь. Помимо необходимых нечетких слов, которые вам нужно иметь в виду с языками со статической типизацией, такими как C и Java, после выполнения некоторых советов и руководств в Интернете мое путешествие по Go, казалось, напомнило мне о той радости, которую я испытал, когда начал изучать Python.

Я рекомендую бесплатную электронную книгу Введение в программирование в Go Калеба Докси, которая является самым простым введением, которое я нашел в Интернете, предназначенным для начинающих. Вы также можете скачать примеры кода и решения проблем из этой книги из моего репозитория на Github здесь.

Go или Golang - это статически типизированный язык с синтаксисом, в значительной степени унаследованным от C, с дополнительными функциями, такими как сборка мусора (например, Java), безопасность типов и некоторые динамические -типирование возможности. разработан в Google в 2007 году группой умных людей, Робертом Гриземером, Робом Пайком и Кеном Томпсоном. Go - это язык программирования общего назначения, ориентированный на работу в Интернете. То, что в значительной степени определяет импульс Go, - это, возможно, его стремление к параллелизму, асинхронности (в Node.js), скорости (в C) и, конечно же, в том, что в наши дни является обязательным элементом любого языка веб-программирования - масштабируемостью.

Установка Go

Go - это скомпилированный язык программирования, который компилируется настолько быстро, что кажется интерпретируемым (таким образом, не ожидайте интерактивной оболочки или режима REPL). Чтобы установить Go и его компилятор (Gc), перейдите на http: //www.golang.or g и загрузите последнюю версию в двоичном формате, затем установите ее. У вас должна получиться структура каталогов, подобная этой:

$HOME
├── Go
    ├── bin
    ├── pkg
    └── src

Если вы используете Mac OSX или Unix, вам нужно экспортировать переменную среды GOPATH в каталог Go, поместите эти строки где-нибудь в своем .bashrc или файл .bash_profile.

В вашем терминале введите go, чтобы открыть несколько команд для опробования (например, go version распечатает вашу установленную версию go.) С этого момента вы можете захотеть создать каталог в ~ / go / src и храните там свои коды.

Привет, Марс!

Чтобы оживить ваши впечатления, давайте начнем с "Привет, Марс!" традиции программирования. Создайте файл с именем hello_mars.go и напишите код:

После сохранения файла запустите:

~$ go run hello_mars.go

Видите ли, вы заранее обнаружите, что Go поддерживает формат UTF-8 из коробки, и это удобно, поскольку Интернет глобален. Приведенный выше код выводит сообщение «Hello Mars!» на английском, китайском и тайском языках.

Если вы программировали на Python, C и / или Java, вы сразу заметите знакомые вещи. Основная программа Go состоит примерно из трех частей: имя пакета, импортированные пакеты и основная функция. Как и в C / C ++, компилятор Go всегда ищет функцию main () для начала. В отличие от C, Go не имеет директив прекомпилятора или включенных файлов заголовков, и именно поэтому он компилируется быстро.

Пакет и импорт

Ключевое слово package - это способ сообщить Go, какой пакет кода вы блокируете и как его можно импортировать. Например, в программе main.go с функцией с именем main вы также должны назвать пакет main. Внутри пакета fmt первая строка кода - это package fmt, которая позволяет импортировать код с помощью import «fmt»

Ниже показано, как выглядит заголовок кода fmt:

// fmt package
package fmt
import (
 “strconv”
 “unicode/utf8"
)
...

После импорта пакета вы можете использовать экспортированные имена пакета. Экспортированные имена (или общедоступные) в Go начинаются с заглавной буквы, что означает, что их можно использовать где угодно. (Помните, что заглавные буквы означают взрослых и готовность исследовать внешний мир. Строчные буквы означают детей ясельного возраста, которые все еще находятся в колыбели кода)

package main
import (“fmt” ; "math")
func main() {
    // use the exported method name
    fmt.Println("Bambi is not a gopher")
    // this will fail
    p := math.pi
}

Go не требует явных точек с запятой `;` в конце операторов, но, как и CoffeeScript, Go имеет неявные невидимые точки с запятой. Таким образом, вы можете и будете использовать точки с запятой там, где это необходимо.

Типы

Типы Go более или менее похожи на C, но имеют более простой синтаксис, который легче запомнить:

  • uint8, uint16, uint32, uint64 - для целых чисел без знака соответствующих размеров.
  • int8, int16, int32, int64 - для целых чисел со знаком соответствующих размеров.
  • byte и rune эквивалентны uint8 и uint32 соответственно
  • int, uint, uintPtr зависят от машины, то есть размеры зависят от архитектуры вашего компьютера (т. е. 32- или 64-разрядной версии).
  • float32 и float 64 для чисел с плавающей запятой.
  • NaN для «не числа», например 0/0
  • complex64 и complex128 для комплексных чисел.
  • строка для строк текста
  • bool для логических значений (true, false)
  • struct и interface - особые типы, которые составляют объектно-ориентированную сторону Go, что мы увидим позже.

Ваши первые переменные

В Go есть довольно уникальный способ объявления переменной, который сильно отличается от синтаксиса в стиле C. Объявление типа всегда находится справа от имени переменной. Этот подход слева направо - там, где нам, людям, легче читать и понимать.

var name string

Выше строка гласит: создать переменную с именем строки типа. Загляните в этот блог, чтобы узнать, почему.

Go определяет тип на основе присвоенного вам значения, а при объявлении переменной даже используется ключевое слово var, как в JavaScript. Для констант используйте ключевое слово const. Вы также можете назначить сразу несколько переменных, выполнив следующие действия:

var (
    a = 45
    b = “Gophers ain't beavers”
    c = 34.01
)

Фактически, к вашему сведению, вы также можете импортировать несколько пакетов таким же образом

import (
    "fmt"
    "net/http"
    "math"
)

Петля (без буквы "s")

Это одна из действительно освежающих функций Go. Go смело выбрала цикл for как единственный цикл на своем языке. В C есть три вида циклов, все с разным синтаксисом и перекрывающейся семантикой. Go удается иметь более выразительную семантику цикла, но простой и единообразный синтаксис.

Также следует отметить, что в Go нет выражения до и после инкремента. Разработчики Go решили просто избавиться от запутанных выражений до и после инкремента в C. Поэтому a ++ - это оператор, и разрешен только суффикс, поэтому вы не может делать что-то вроде b: = a ++ или ++ a.

Существуют специальные формы цикла for, которые просто великолепны и будут представлены соответствующим образом, когда мы будем говорить о массивах, срезах и картах.

Если и Switch

В приведенном выше фрагменте выполняется цикл по целому числу от 1 до 10 и выводится строка «четное» для четных значений и «нечетное» для нечетных значений. Обратите внимание, что операторы if и for do не требуют скобок. Фактически, Go не допускает их даже в условных выражениях и циклах.

Оператор Switch достаточно прост и ничем не отличается от C. В приведенном ниже коде используется метод Scanf () пакета fmt, который запрашивает ввод данных пользователем. Затем он печатает английскую строку, соответствующую полученному числу до 5.

Массивы, фрагменты и карты

Как и Python, Go поддерживает списки и карты. Однако, будучи статически типизированными, каждое из них может содержать значения только одного типа.

Массив - это нумерованная последовательность элементов одного типа фиксированной длины. Чтобы создать массив, вы делаете что-то вроде этого:

var x [5]int        // remember the type is always on the right

Это создает массив целых чисел длиной 5.

Массивы изменяемы, то есть их значения могут быть изменены позже. Ниже мы создаем пустой массив x и присваиваем 100 последнему члену x.

Когда вы запустите программу с помощью go run array.go, программа распечатает [0 0 0 0 100 ]. Одна вещь, которую вам нужно запомнить, исходя из других языков, заключается в том, что когда вы объявляете переменную любого типа без присвоения значения, вы устанавливаете ее в 0. Это большое удобство, потому что, как вы получаете undefined в неназначенных переменных JavaScript, он защищает вашу программу от любых сбоев во время выполнения.

Чтобы перебрать массив, мы просто используем цикл for, как в C / C ++. Этот код распечатает все элементы массива arr.

Обратите внимание, что мы использовали литерал массива, чтобы инициировать массив и сразу же назначать элементы. Это также можно сделать в отдельных строках, например так:

var arr = [10]int{
    1, 21, 35, 4, 30,
    6, 12,  9, 4, 10,
}

Однако я сказал, что существует особая форма цикла for, предназначенная исключительно для обхода списка, и вот она.

for i, v := range arr {}

i обозначает текущую позицию или индекс в arr, как и в предыдущем цикле, в то время как v эквивалентен в arr [i]. Неважно, какие буквы вы используете для переменных, когда вы используете эту форму цикла, первая переменная после ключевого слова for будет индексом, а (необязательно) вторая переменная после запятой будет соответствующим значением. array_loop.go можно переписать следующим образом:

Мы используем `_` вместо i, потому что Go не разрешит лежать неиспользуемые переменные и будет жаловаться на это, а подчеркивание - это (js-удобный) способ разрешить компилятор знает, что можно выбросить переменную.

Этот вид цикла for исключительно удобен, поскольку выяснение того, когда и где остановиться в массиве, может быть излишне болезненным, и иногда вы можете даже не знать, сколько членов имеет список. Языки сценариев, такие как Python и Ruby, используют эту форму цикла, и даже JavaScript недавно представил метод forEach (), который помогает применять функцию к каждому члену массива.

Срезы похожи на массивы, за исключением того, что длина не фиксирована, хотя и ограничена. Вы можете думать о срезах как о векторах в C ++ с ограниченной длиной. Срез связан с массивом. Мы как бы выделяем массив в памяти компьютера, затем создаем и связываем с ним срез. Чтобы создать срез, вы просто создаете массив пустого размера:

var x []string

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

var x= make([]string, length, capacity)

Необязательный аргумент емкость - это максимальная емкость, до которой может добраться срез. Как видите, срез - это нарезанный массив.

Фактически, вы даже можете создать срез с помощью оператора [low: high], как сращивание списка в Python.

var creatures = [4]string{"Pokemon", "Furby", "Unicorn", "Gopher"}
var s1 = creatures[0:2]          // [Pokemon Furby]
var s2 = creatures[:4]           // [Pokemon Furby Unicorn Gopher]
var s3 = creatures[1:]           // [Furby Unicorn Gopher]
var s4 = creatures[:]            // [Pokemon Furby Unicorn Gopher]
var s5 = creatures[2:len(creatures)] // [Unicorn Gopher]

Go имеет две встроенные функции для работы со срезами - append и copy. Они достаточно просты, чтобы вы могли примерить их на себе.

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

var x map[string]int

Нам нужно ключевое слово map перед квадратными скобками, которое явно сообщает Go, что индекс или ключ является строкой. Карты, как и фрагменты, необходимо инициализировать с помощью функции make. Карты полезны для хранения структурированной общей информации.

Этот код распечатает следующее:

Gopher with the power of digging
Pokemon with the power of lightning
Unicorn with the power of flying
Furby with the power of nagging
F's name is Furby
G's color is blue

Мой опыт знакомства с Го похож на то, что я возвращаюсь к бывшей девушке, когда я понял, что она изменилась, и заставил вас задуматься, почему вы расстались. Go очень универсален, и в нем были проработаны все укромные уголки и трещины, благодаря которым такая красота, как C ++, стала проблемой на сегодняшний день. Я никогда не использовал статически типизированный язык для каких-либо веб-проектов, но я действительно собираюсь это сделать.

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