Из техпода в программисты (или Golang для самых маленьких)

465fa6236c14aada6cf5031c4f6b6bcd

Доброго времени суток, Хабровчане!  

Предисловие

Мне 26 лет, 5.5 лет проработал в технической поддержке и окончательно выгорел. Решил заниматься тем, что меня действительно воодушевляет и от чего испытываю удовольствие. 

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

На своём жизненном пути я уже знакомился с HTML, CSS и его препроцессорами, Javascript, PHP, SQL, немного Python, C#, Java. Даже реализовал несколько веб проектов, решил некоторые рабочие задачи, но меня постоянно что-то не устраивало. Я хотел найти «идеальный» для себя язык с которым мне было бы приятно работать и наткнулся на Golang.

Почему именно Golang? Go понравился мне по нескольким причинам.

  1. Молодой

  2. Компилируемый

  3. Строго типизированный

  4. «Из коробки» имеет многопоточность

  5. Сборщик мусора о котором нет необходимости задумываться

  6. Развивается как open source проект

Что рассмотрим в этой статье

  • Что нужно для работы с Go

  • Переменные

  • Основные типы данных

  • Константы

  • Арифметические операции

  • Комментарии

  • Ввод/вывод данных

  • Условные выражения и условные конструкции

Что нужно для работы с Go

Для работы с Go первое что необходимо это — текстовый редактор для написания кода, а так же компилятор который преобразует код в исполняемый файл.

Скачайте и установите компилятор с официального сайта — https://golang.org/dl/

Для написания кода можно использовать специальные интегрированные среды разработки (IDE), которые поддерживают Go.

Самая многофункциональная IDE представлена компанией JetBrains и называется она GoLand, но не спешите её устанавливать. Есть ряд причин почему нет необходимости в таком большом инструменте.

  1. стоит денег

  2. для знакомства с языком и написания своих первых пет-проектов хватит и инструментов описанных ниже

Другие инструменты для разработки на Go:

  • Visual Studio Code + плагин для разработки на Go

  • Atom + плагин для разработки на Go

  • Sublime Text + плагин для разработки на Go

  • Lite IDE (чем сам пользуюсь)

Существуют и другие IDE у которых есть плагины для Go например: Intellij IDEA, Netbeans. Но не думаю что стоит заострять на них внимание т.к. это достаточно большие IDE с обширным функционалом и новичок в них очень легко запутается.

Также можно программировать на Go прямо из браузера не устанавливая ничего на своё устройство.

Переменные

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

var имя_переменной тип_данных

В Go имя переменной может быть произвольным и может состоять из алфавитных и цифровых символов, а также символа подчеркивания. При этом при объявлении переменной первый символ должен быть либо алфавитный символ, либо символ подчеркивания. Важно, что имена переменных не могут быть такими же как зарезервированные в Go кодовые слова: break, case, chan, const, continue, default, defer, else, fallthrough, for, func, go, goto, if, import, interface, map, package, range, return, select, struct, switch, type, var.

Самое простое определение переменной:

var hello string

Эта переменная называется hello и представляет строковый тип данных string.

Можно одновременно объявить несколько переменных через запятую:

var a, b, c string

В этом случае объявлены переменные a, b и c которые имеют тип данных string. В конце также указывается тип данных и все переменные ему принадлежат.

Одновременно с объявлением переменной ей можно присвоить какое-то значение:

var name string = "Авдей”
var a int = 10
var b float64 = 1.0654312

Такой прием называется инициализацией

Неявная типизация

При объявлении переменной можно не указывать её тип, если происходит явная инициализация переменной значением.

var name = "Авдей"

Так же можно объявить переменную сокращенным способом:

name := "Авдей"

Такой способ эквивалентен предыдущему.

Если объявить переменную без указания типа и начального значения, это будет ошибкой.

var name

Поэтому необходимо либо указать тип, либо начальное значение, либо и то и другое

var name string
var name = "Авдей"
var name string = "Авдей"

Так же можно объявить несколько переменных

var (
	name = "Авдей"
	gender = "Мужчина"
	age = 99
)

или

var name, gender, age = "Авдей", "Мужчина", 99

Основные типы данных

Числовые типы

Стандартное значение для всех числовых типов = 0

Целочисленные типы

int8 — число от -128 до 127 занимает в памяти 1 байт (8 бит).

int16 — число от -32768 до 32767 занимает в памяти 2 байта (16 бит).

int32 — число от -2147483648 до 2147483647 занимает в памяти 4 байта (32 бита).

int64 — число от -9 223 372 036 854 775 808 до 9 223 372 036 854 775 807 занимает в памяти 8 байт (64 бита).

uint8 — целое число от 0 до 255 занимает 1 байт.

uint16 — целое число от 0 до 65535 занимает 2 байта.

uint32 — целое число от 0 до 4294967295 занимает 4 байта.

uint64 — целое число от 0 до 18 446 744 073 709 551 615 занимает 8 байт.

byte — тоже самое что и uint8, целое число от 0 до 255 занимает 1 байт.

rune — тоже самое что и int32, число от -2147483648 до 2147483647 занимает в памяти 4 байта (32 бита).

int — аналог int32 или int64 целое число которое в зависимости от разрядности операционной системы может занимать либо 4 либо 8 байт.

uint — целое беззнаковое число, аналог типа int, соответствует типам int32 и int64 занимает 4 или 8 байт.

Тип с плавающей точкой

Они же десятичные дроби.

float32 — число с плавающей точкой от 1.410–45 до 3.41038 (для положительных). Занимает в памяти 4 байта (32 бита).

float64 — число с плавающей точкой от 4.910–324 до 1.810308 (для положительных) и занимает 8 байт (64 бита).

Комплексные типы

В Go присутствуют комплексные типы данных. На практике они имеют не очень большую популярность.

complex64 — комплексное число где вещественная и мнимая части представляют числа float32.

complex128 — комплексное число где вещественная и мнимая части представляют float64.

Пример использования:

var c1 complex64 = 1+2i
var c2 complex128 = 2+3i

Подробнее про комплексные числа можете прочитать здесь

Логический тип

bool — логический тип данных и может иметь только 2 значения true (истина) или false (ложь)

Пример использования:

var isEnabled bool = true
var isDisabled bool = false

Строковый тип

string — В Go строки это последовательность символов заключенная в двойные кавычки

var language string = "Go"

Помимо обычных символов строка может содержать в себе специальные символы

\n — переход на новую строку

\r — возврат каретки (возвращает курсор в начало текущей строки)

\t — табуляция

» — двойная кавычка внутри строк

Константы

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

Для определения константы используется ключевое слово const.

const pi float32 = 3.1415

Если мы попробуем изменить значение константы, то получим ошибку.

const pi float32 = 3.1415
pi = 6.5535	// ошибка

В одном представлении можно объявить сразу несколько констант

const (
	pi float32 = 3.1415
	Ferma int = 65535
)

Если у константы не указан тип, то он выводится неявно в зависимости от того значения каким инициализируется константа

const a = 17 // тип int

Также константам обязательно необходимо присваивать значения при объявлении.

const a
const b int
const c float32
const d string

Такое объявление констант недопустимо, потому что они не инициализируются.

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

const (
	a = 1
	b
	c
	d = 2
	e
)

fmt.Println(a, b, c, d, e)	// 1, 1, 1, 2, 2

Важно, константы можно инициализировать только константными значениями, например числами, строками или значениями других констант. Но инициализировать константу значениями переменной нельзя:

var a int = 123
const b = a		// Ошибка. a - переменная
const c = 321		// ОК, 321 - числовая константа
const d = c		// ОК, c является константой

Арифметические операции

У переменных есть разные операции, как в алгебре.

+ сложение

— вычитание

* умножение

/ деление

a := 100
b := 50

c := a + b	// c = 150
c := a - b	// c = 50
c := a * b	// c = 5000
c := a / b	// c = 2

При делении необходимо быть внимательным! Если в операции два целых числа, то результат деления будет округляться до целого числа даже если результат деления присваивается переменной типа float32/float64:

var a float32 = 7 / 2		// 3

Чтобы получить в результате деления вещественное число, хотя бы один из операндов должен быть вещественным числом:

var a float32 = 7.0 / 2	// 3.5

% (деление по модулю) возвращает остаток от деления. В этой операции могут быть использованы только целые числа:

var b int = 20 % 6	// 2 (20 - 18 = 2)

Постфиксный инкремент (x++). Увеличивает значение переменной на единицу:

var a int = 15
a++
fmt.Println(a)		// 16

Постфиксный декремент (x--). Уменьшает значение переменной на единицу:

var a int = 15
a--
fmt.Println(a) 	// 14

Комментарии

Программа может содержать в себе комментарии. Комментарии необходимы для описания действий которые производит программа или какие-то её части. При компиляции программы комментарии не учитываются и не оказывают никакого влияния на работы программы. Комментарии бывают однострочными и многострочными.

Однострочный комментарий пишется в одну строку после двойного слеша (//), многострочный комментарий может заключаться между символами /* и */ и занимать несколько строк:

/*
	Первая программа
	на языке Golang
*/
package main	// определения пакета файла

import "fmt”		// подключение пакета fmt

// определение функции main

func main() {
	fmt.Println("Hello, Go!”)	// вывод строки в консоль
}

Ввод/вывод данных

Работать с переменными конечно интересно, но намного интереснее работать с ними и видеть как их значения выводятся через консоль. Для того чтобы это сделать, необходимо воспользоваться методом Scan из стандартного пакета Go под названием fmt, например:

fmt.Scan(&a)

&a — ссылка на переменную (или адрес переменной) под названием a

Если проще, то введённое число или слово в консоль, запишется в эту переменную и будет в ней храниться пока не понадобится изменить значение переменной.

Теперь можно прочитать например, имя и возраст. Для начала создадим файл в любом удобном для вас месте на вашем компьютере. В моём случае это файл main.go расположенный по пути E:\main.go и содержит в себе следующий код:

package main

import "fmt”

func main() {
	var name string
	var age int
	fmt.Print("Введите имя: ”)
	fmt.Scan(&name)
	fmt.Print("Введите возраст: ”)
	fmt.Scan(&age)

	fmt.Printf("Человеку по имени %v, %v лет.", name, age)
}

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

Далее чтобы увидеть работу этого кода и поиграть с ним, необходимо запустить командную строку или терминал. Например: Git Bash, встроенный терминал LiteIDE. Если пользуетесь этой IDE как я, терминал можно запустить сочетанием клавиш Ctrl+Shift+4. Итак, вводим заветную команду go run main.go и нажимаем Enter.

После консоль просит нас по очереди ввести имя и возраст. Когда программа получает эту информацию, выводится строка «Человеку по имени Авдей, 99 лет.» и программа завершает свою работу.

$ go run main.go
Введите имя: Авдей
Введите возраст: 99
Человеку по имени Авдей, 99 лет.

Условные выражения и условные конструкции

Условные выражения представляют операции отношения и логические операции. Они представляют условие и возвращают значение типа bool: true — если условие истинно и false — если условие ложно.

Операции отношения позволяют сравнивать два значения. В Go есть следующие операции отношения:

== Операция «равно», возвращает true, если оба операнда равны или false если они не равны.

> Операция «больше чем», возвращает true, если первый операнд больше второго, и false если первый операнд меньше второго, либо оба операнда равны.

< Операция «меньше чем», возвращает true, если первый операнд меньше второго, и false если первый операнд больше второго, либо оба операнда равны.

>= Операция «больше или равно», возвращает true, если первый операнд больше второго или равен второму, и false если первый операнд меньше второго.

<= Операция «меньше или равно», возвращает true, если первый операнд меньше или равен второму, и false если первый операнд больше второго.

!= Операция «не равно», возвращает true, если первый операнд не равен второму, и false если оба операнда равны.

Логические операции сравнивают два условия. Они применяются к отношениям и объединяют несколько операций отношения. К логическим операциям относятся:

! — операция отрицания (логическое НЕ). Инвертирует значение. Если операнд равен true, то возвращает false. И наоборот, если операнд равен false, вернет true.

&& — конъюнкция, логическое умножение (логическое И). Возвращает true, если оба операнда не равны false. Возвращает false, если хотя бы один операнд равен false.

|| — дизъюнкция, логическое сложение (логическое ИЛИ). Возвращает true, если хотя бы один операнд не равен false. Возвращает false, если оба операнда равны false.

Примеры использования операций отношения и логических операций можете посмотреть здесь.

Условные конструкции проверяют истинность условия и в зависимости от результата проверки направляют ход программы по одному из путей.

if else

Конструкция if принимает условие — выражение, которое возвращает значение типа bool. И если это условие истинно, то выполняется последующий блок инструкций:

package main

import "fmt"

func main() {
	x := 12
	y := 13

	if x < y {
		fmt.Println("x меньше y")
	}
}

В приведенном примере после запуска кода, консоль выведет «x меньше y».

$ go run main.go
x меньше y

Если необходимо задать программе альтернативную логику, которая выполнится в случае если условия верно, то добавляется выражения else:

package main

import "fmt"

func main() {
	x := 13
	y := 12

	if x < y {
		fmt.Println("x меньше y")
	} else {
		fmt.Println("x больше y")
	}
}

В этом примере после запуска кода, консоль выведет «x больше y» т.к. условие в блоке else будет верным.

$ go run main.go
x больше y

Если необходимо проверить несколько альтернативных вариантов, то можно добавить выражение else if:

package main

import "fmt"

func main() {
	x := 13
	y := 13

	if x < y {
		fmt.Println("x меньше y")
	} else if x > y {
		fmt.Println("x больше y")
	} else {
		fmt.Println("x равно y")
	}
}

В этом случае выполнится код в блоке else, потому как условия описанные в блоках if и else if равны false.

$ go run main.go
x равно y

Выражений else if может быть множество.

Switch

Конструкция switch проверяет значение выражения, с помощью операторов case определяются значения для сравнения. Если значение после оператора case совпадает со значением выражения switch, то выполняется код этого блока case.

package main

import "fmt"

func main() {
	x := 7

	switch x {
	case 0:
		fmt.Println("Zero")
	case 1:
		fmt.Println("One")
	case 2:
		fmt.Println("Two")
	case 3:
		fmt.Println("Three")
	case 4:
		fmt.Println("Four")
	case 5:
		fmt.Println("Five")
	case 6:
		fmt.Println("Six")
	case 7:
		fmt.Println("Seven")
	default:
		fmt.Println("Unknown Number")
	}
}

Запустив этот код, мы увидим что выполнится case 7, потому что значение в этом кейсе совпадает со значением в switch.

$ go run main.go
Seven

Также в приведенном выше коде написан блок default. Этот блок не обязательный, но он выполнится если ни один из операторов case не содержит нужного значения.

Стоит отметить, что в Go код после case выполняется до следующего case, то есть нет необходимости заканчивать каждый блок case словом break. Это было добавлено в язык специально, чтобы уменьшить количество ошибок в блоках switch. Если в текущем блоке написать ключевое слово fallthrough, то следующий case выполнится вне зависимости от того, истинно ли его условие:

package main

import "fmt"

func main() {
	x := 4

	switch x {
	case 0:
		fmt.Println("Zero")
		fallthrough
	case 1:
		fmt.Println("One")
		fallthrough
	case 2:
		fmt.Println("Two")
		fallthrough
	case 3:
		fmt.Println("Three")
		fallthrough
	case 4:
		fmt.Println("Four")
		fallthrough
	case 5:
		fmt.Println("Five")
		fallthrough
	case 6:
		fmt.Println("Six")
		fallthrough
	case 7:
		fmt.Println("Seven")
		fallthrough
	default:
		fmt.Println("Unknown Number")
	}
}

Выполнив этот код, мы увидим следующую картину в консоли:

$ go run main.go
Four
Five
Six
Seven
Unknown Number

В консоль будет выведено всё начиная с 4 кейса, т.к. значение лежащее в переменной x равно 4, а остальные case выполнятся из-за того, что внутри case написано ключевое слово fallthrough.

В switch допускается использование произвольных условий в каждом case:

package main

import "fmt"

func main() {
	var x uint16
	fmt.Scan(&x)

	switch {
	case 1 <= x && x <= 20:
		fmt.Println("Вы написали число от 1 до 20")
	case 21 <= x && x <= 400:
		fmt.Println("Вы написали число от 21 до 400")
	case 401 <= x && x <= 1000:
		fmt.Println("Вы написали число от 401 до 1000")
	}
}

Если запустить этот код и ввести допустим число 256, то получим в консоли:

$ go run main.go
256
Вы написали число от 21 до 400

Заключение

В заключении статьи хотелось бы поделиться полезными ссылками:

Официальная документация. (исключительно на английском языке).

Руководство по языку Go от Metanit. В статье уже ссылался на этот ресурс.

Книга — Golang для профи. Работа с сетью, многопоточность, структуры данных и машинное обучение с Go | Цукалос Михалис. (Для новичков будет не совсем понятна, хоть и позиционируется как для начинающих разработчиков, так и для тех, кто работает не один год.)

50 оттенков Go. Очень полезная статья, спасибо VK Team за перевод оригинала

Самый наглядный ресурс для изучения Git по моему мнению

Для тех кто любит проходить различные курсы:

Программирование на Golang (курс составлен неплохо, но полные новички возможно испытают некоторые сложности из-за того, что нельзя посмотреть какими тестами облагаются задания)

Разработка веб-сервисов на Go — основы языка. Курс от Mail.ru и МФТИ. Для полных новичков будет сложно, но по завершению выдаётся сертификат.

Разработка веб-сервисов на Golang, часть 2. 

Ресурсы с заданиями для практики:

CodeWars

Exercism. Имеется множество заданий различной сложности. Можно быть как студентом, так и ментором.

Спасибо за внимание. До новых встреч! Комментарии в студию :)

© Habrahabr.ru