Go Шпаргалка по языку программирования
Go (также известный как Golang) — это статически типизированный компилируемый язык, разработанный Робертом Гризмером, Робом Пайком и Кеном Томпсоном в Google. Синтаксис Go схож с C, но обладает такими особенностями, как безопасность памяти, GC (сборка мусора), структурная типизация и конкурентность в стиле CSP.
Hello world
package main
import "fmt"
func main() {
message := greetMe("world")
fmt.Println(message)
}
func greetMe(name string) (string) {
return "Hello, " + name + "!"
}
$ go buildПеременные
Объявление переменных
var msg string
msg = "Hello"Краткая форма
msg := "Hello"Константы
const Phi = 1.618Константы могут быть символами, строками, логическими или числовыми значениями.
Базовые типы
Строки (Strings)
str := "Hello"
str := `Многострочная
строка`Тип строк — string.
Числа
Типичные типы
num := 3 // int
num := 3. // float64
num := 3 + 4i // complex128
num := byte('a') // byte (псевдоним для uint8)Другие типы
var u uint = 7 // uint (беззнаковое)
var p float32 = 22.7 // 32-битный floatУказатели
func main () {
b := *getPointer()
fmt.Println("Value is", b)
}
func getPointer () (myPointer *int) {
a := 234
return &a
}Указатели указывают на адрес переменной в памяти. В Go реализована полноценная сборка мусора.
Массивы (Arrays)
// var numbers [5]int
numbers := [...]int{0, 0, 0, 0, 0}Массивы имеют фиксированный размер.
Срезы (Slices)
slice := []int{2, 3, 4}
slice := []byte("Hello")В отличие от массивов, срезы имеют динамический размер.
Управление потоком
Условные операторы
if day == "sunday" || day == "saturday" {
rest()
} else if day == "monday" && isTired() {
groan()
} else {
work()
}Инструкция внутри if
if _, err := getResult(); err != nil {
fmt.Println("Uh oh")
}Оператор if может выполнять простую инструкцию перед проверкой условия.
Switch
switch day {
case "sunday":
// в Go нет автоматического перехода (fall through)!
fallthrough
case "saturday":
rest()
default:
work()
}Функции
Лямбда-функции (анонимные)
myfunc := func() bool {
return x > 10000
}Функции в Go являются объектами первого класса.
Несколько возвращаемых значений
a, b := getMessage()
func getMessage() (a string, b string) {
return "Hello", "World"
}Именованные возвращаемые значения
func split(sum int) (x, y int) {
x := sum * 4 / 9
y := sum - x
return
}Если возвращаемые значения названы при объявлении, пустой оператор return вернет переменные с этими именами.
Пакеты (Packages)
Импорт
import "fmt"
import "math/rand"
import (
"fmt" // дает доступ к fmt.Println
"math/rand" // дает доступ к rand.Intn
)Оба способа идентичны.
Псевдонимы (Aliases)
import r "math/rand"
r.Intn()Экспортируемые имена
func Hello () {
···
}Экспортируемые имена должны начинаться с заглавной буквы.
Пакеты
package helloКаждый файл пакета должен начинаться с инструкции package.
Конкурентность
Горутины (Goroutines)
func main() {
// Канал (channel)
ch := make(chan string)
// Запуск конкурентных функций
go push("Moe", ch)
go push("Larry", ch)
go push("Curly", ch)
// Чтение 3 результатов
// (Так как горутины работают конкурентно,
// порядок не гарантирован!)
fmt.Println(<-ch, <-ch, <-ch)
}
func push(name string, ch chan string) {
msg := "Hey, " + name
ch <- msg
}Каналы — это безопасные для конкурентного использования объекты связи между горутинами.
Буферизованные каналы
ch := make(chan int, 2)
ch <- 1
ch <- 2
ch <- 3
// fatal error:
// all goroutines are asleep - deadlock!Буферизованные каналы ограничивают количество сообщений, которые они могут хранить.
Закрытие каналов
Закрывает канал
ch <- 1
ch <- 2
ch <- 3
close(ch)Итерация по каналу до его закрытия
for i := range ch {
···
}Канал закрыт, если ok == false
v, ok := <- chDefer & Panic
Defer
func main() {
defer fmt.Println("Готово")
fmt.Println("Работаем...")
}Откладывает выполнение функции до момента выхода из текущей функции. Аргументы вычисляются немедленно, но сам вызов происходит в конце.
Defer с лямбда-функциями
func main() {
defer func() {
fmt.Println("Готово")
}()
fmt.Println("Работаем...")
}Анонимные функции лучше подходят для блоков defer.
Структуры (Structs)
Определение
type Vertex struct {
X int
Y int
}
func main() {
v := Vertex{1, 2}
v.X = 4
fmt.Println(v.X, v.Y)
}Литералы
v := Vertex{X: 1, Y: 2}
// Имена полей можно опустить
v := Vertex{1, 2}
// Y подразумевается
v := Vertex{X: 1}Вы также можете указывать имена полей.
Указатели на структуры
v := &Vertex{1, 2}
v.X = 2Если v является указателем, запись v.X эквивалентна (*v).X.
Методы
Получатели (Receivers)
type Vertex struct {
X, Y float64
}
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X * v.X + v.Y * v.Y)
}
v := Vertex{1, 2}
v.Abs()В Go нет классов, но вы можете определять функции для типов, используя получатели.
Указатели-получатели
func (v *Vertex) Scale(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
v := Vertex{6, 12}
v.Scale(0.5)
// `v` обновится