Go
Golang
Go - это компилируемый язык созданный Робом Пайком (Google) с поддержкой статической типизации, сборкой мусора и встроенной многопоточностью.
Быстрая разработка
Производительный код
Быстрая сборка
Упрощенное управление зависимостями
Миниатюрные исполняемые файлы без зависимостей
Простое введение https://www.youtube.com/watch?v=qFoG8rDOyeM
Более полное https://www.youtube.com/watch?v=1V5GAYoaKRE
Где скачать https://golang.org/
Goland IDE
Где скачать https://www.jetbrains.com/go Настройка меню File/Settings... GOROOT - указать путь к папке с Golang (в ней будут папки api,bin,lib и тд) GOPATH - для Global и Project обычно выбирают папку на уровень выше чем GOROOT (там создастся папка pkg)
Базовый синтаксис Go
Переменная окружения, ссылка на workspace
$GOPATH/src Путь к модулям
go build ./app.go
go install // компиляция
go run ./app.go // компиляция и запуск GODEBUG=gctrace=1
go tool compile module.go // get .o file
go get github.com/foo/bar // download an internal package
go clean -i -v -x github.com/foo/bar // delete a package
go install
Объявление переменной
var name bool = false
var counter int = 0
или короткий синтаксис (тип назначается по значению)
some := "text"
words := []string{'ready', 'steady'} // тип слайс, динамически расширяемый массив
words = append(words, 'go')
dict := map[string]int{"one": 1, "two": 2}
Только явные преобразование типов
var f32 float32 = 3.14
var f64 float64 = float64(f32)
Объявление функций
func name(byRef *type, byValue type) int { ... }
func Two() (int, int) {return 1, 2} // возврат нескольких значений
func Two() (one int, two int) {} // результаты могут иметь названия
func main() {..} // точка входа
Структуры данных
type person struct {
name string
age int
}
p := person{name: "Mike", age: 30}
Объявление метода для структуры и вызов метода
func (p person) NickName() string {
return p.name + strconv.Itoa(p.age)
}
fmt.Println(p.NickName())
fmt.Println(person.NickName(p)) // или так
В структуре может быть ссылка на другую структуру
type circle struct {
center *point
}
Форматирование вывода
import "fmt"
fmt.Printf("Name: %s, age: d%\n", p.name, p.age)
Передача параметра по указателю
c := circle{center: point{x:1 , y:1}, radius: 1}
updateRadius(&c)
fun escapes() *circle {
n := circle{center: point{x:3 , y:3}, radius: 3}
return &n
}
Использование range
arr := [5]int(0, 1, -1, 2, -2)
for index, value := range arr {
fmt.Println("index ", index, " value ", value)
}
Обработка ошибок
defer функция отрабатывает перед завершением функции, ее целесообразно использовать например для закрытия соединения с БД
func writeData(data []string) (string, error) {
filename := "./data" + strconv.Itoa(rand.Int()) + ".txt"
file, err := os.Create(filename)
if err != nil {
return "", fmt.Errorf("writing file: %v", err)
}
defer file.Close() // отложенный вызов сработает при выходе из функции
err = doWrite(file, data)
if err != nil {
return "", fmt.Errorf("writing file: %v", err)
}
return filename, nil
}
Эмуляция unchecked exception в Go
defer func() {
val := recover() // словить исключение, если оно было
if val != nil { исключение поймано }
}
panic("message") // выбросить исключение
Вместо наследования используется композиция
type employee struct {
person // доступны все поля структуры person
jobTitle string
}
emp.person.name // можно обратится так
emp.name // а можно так
p.NickName() // и обратится к его методам
Можно создавать интерфейсы
type NickNamed interface {
NickName() string
}
Запуска функций в отдельном потоке (Goroutine)
nums := make(chan int, 5) // создание буферизированного канала
go produces(nums) // запуск го-рутин, запись в канал nums <- value
// close(nums) - закрыть канал
consumer(nums) // передаем канал для общения, чтение value <- nums
Передача канала в качестве параметра
c: make(chan string) // тип канала может быть каналом :-)
func foo(name chan string) {}
close(c) // закрыть канал, принимающая сторона больше не будет ожидать данные
value, open := <- c // open после закрытия канала вернет false
с := range c { .. } // избавляет нас от проверки закрытия канала
Одновременное получение данных из разных каналов
go first(one)
go second(two)
for {
select {
case o := <-one:
case t := <-two:
}
}
Ожидание завершения goroutine
import "sync"
var wg sync.WaitGroup
wg.Add(1) // завершение скольких goroutine мы ждем
go func() {
someFunction() // эта функция запущена внутри го рурины
wg.Done() // уменьшаем counter установленный wg.Add
}()
wg.Wait() // ждем завершения всех горутин
Unit test, запуск go test --cover
package main
import "testing"
func TestName(t *testing.T) {
name := getName()
if name != "World!" {
t.Error("Respone from getName is unexpected value")
}
}
Присваивание с одновременной проверкой ошибки в одну строку if result, err := Intersection(l1, l2); err == nil {...}
Темы для изучения
Концепция обработки ошибок в языке
Defer
Go-рутины
Механизмы обмена данными в Go
Обмен сообщениями: каналы (встроены в язык), подходит для: Обмен данными (pipelines), Распределение задач, Передача асинхронных результатов
Разделяемая память: mutex'ы (стандартная библиотека), подходит для: Кеши, State
файлы go.mod и go.sum
создание файла зависимостей go mod init example.com/hello
gRPC
Пример разработки gRPC микросервиса с использование ProtoBuff
Разработка микросервисов
Web
Gin - HTTP framework и пример использования
Chi - Gin is a web framework written in Go (Golang). It features a martini-like API with performance that is up to 40 times faster thanks to httprouter.
Тестирование
packages: fmt, os, time, net, net/http, flag, encoding/json, path, strings, regexp, runtime, errors, reflect, strconv, unsafe
package - работа с пакетами
&, *
установка модулей go get ...
range инетрировать по элементам один за другим
for _, v := range a { c <- v }
for word, count := range w.found {}
if c := recover(); c != nil { fmt.Println("Recover inside a()!") }
альтернатива do..while = for ok := true; ok; ok = anExpression { }
альтернатива while = for scanner.Scan() {}
sync
sync.Mutex - блокирование совместно используемого блока кода или переменных при параллельном выполнении
log
log.Println("This is a regular message.")
log.Printf("The value of i is %s", i).
runtime/debug
debug.PrintStack()
runtime.Stack(buf, false) // write stack to a buffer
Шаблоны проектирования
Constructor method, NewFoo() *Foo - создание экземпляров
Interface Wrapper - добавление функциональности в существующие struct's
Swagger - пошаговый пример использования Swagger/OpenApi для генерациии стабов клиента TypeScript и сервера Go/Gin
Библиотеки
go-func - Различные типы итераторов по слайсам и других функциональных мелочей
Gioui - библиотека для разработки UI Windows/Linux/Mac/Web/Mobile
Введение https://www.youtube.com/watch?v=segijy6UcMI
Запуск примера gioui под windows (другая платформа смотрите на сайте gioui.org)
go mod init ваше_имя_проекта
go get gioui.org/example/hello
go build -ldflags="-H windowsgui" gioui.org/example/hello
Дополнительные источники
Стартовая точка https://go.dev
Рекомендуемые книги
Effective Go https://golang.org/doc/effective_go
Go in Practice by Matt Butcher, Matt Farina
Mastering Go by Mihalis Tsoukalos
Go Programming by Example by Agus Kurniawan
Исходные коды проектов на Go (обратитесь к менеджеру)
Last updated
Was this helpful?