Go
Golang
Last updated
Was this helpful?
Golang
Last updated
Was this helpful?
Go - это компилируемый язык созданный Робом Пайком (Google) с поддержкой статической типизации, сборкой мусора и встроенной многопоточностью.
Быстрая разработка
Производительный код
Быстрая сборка
Упрощенное управление зависимостями
Миниатюрные исполняемые файлы без зависимостей
Где скачать 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 {...}
Темы для изучения
Dependency managers
Концепция обработки ошибок в языке
Defer
Go-рутины
Механизмы обмена данными в Go
Обмен сообщениями: каналы (встроены в язык), подходит для: Обмен данными (pipelines), Распределение задач, Передача асинхронных результатов
Конвейеры
Разделяемая память: mutex'ы (стандартная библиотека), подходит для: Кеши, State
файлы go.mod и go.sum
создание файла зависимостей go mod init example.com/hello
gRPC
Разработка микросервисов
Web
Тестирование
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
Библиотеки
Введение 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
Дополнительные источники
Рекомендуемые книги
Go in Practice by Matt Butcher, Matt Farina
Mastering Go by Mihalis Tsoukalos
Go Programming by Example by Agus Kurniawan
Исходные коды проектов на Go (обратитесь к менеджеру)
с использование ProtoBuff
и пример
- 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.
Mock
Testify
Ginkgo
Gomega
Swagger - использования Swagger/OpenApi для генерациии стабов клиента TypeScript и сервера Go/Gin
- Различные типы итераторов по слайсам и других функциональных мелочей
- библиотека для разработки UI Windows/Linux/Mac/Web/Mobile
Стартовая точка
Доклад
Effective Go