МенюЗакуска
Краткий обзор синтаксиса Go
Основные блюда
Возможности платформыИнструментарий
Десерт
Очень субъективное мнение прожжёного “джависта”
МенюЗакуска
Краткий обзор синтаксиса Go
Основные блюда
Возможности платформыИнструментарий
Десерт
Очень субъективное мнение прожжёного “джависта”
МенюЗакуска
Краткий обзор синтаксиса Go
Основные блюда
Возможности платформыИнструментарий
Десерт
Очень субъективное мнение прожжёного “джависта”
Где используется?
https://github.com/golang/go/wiki/GoUsers
Google, Docker, Heroku, Cloud Foundry, CoreOS, InfluxDB, Dropbox, OpenShift, SoundCloud, Toggl, etc.
Короче, в облаках
“Can't reach the pedals. no brakes. gaining speed. eyes bulging in horror. technical debt crash eminent. “
— Tim Dysinger, @dysinger
Не достаёт до педалей. Нет тормозов. Набирает скорость. Глаза полны ужаса. Знаменит катастрофой технического долга
Paul Phillips @extempore2
“go is a terrible, terrible language, yet still a major productivity boost. Amdahl's law in another context.”
“You often see languages which are fighting the last war. Go is fighting the War of 1812.”
“reduce: what you will do with your expectations after you start with Go”
“Rust and Scala drown you in complexity. Go drowns you in simplicity.”
Paul Phillips @extempore2
package main
import "fmt"
func main() { fmt.Println("Hello, Devclub!") }
Реакиця Java-программиста на названия функций с заглавной буквы
func main() { fmt.Println("1 + 2 =", add(1, 2)) }
func add(a int, b int) int { return a + b }
Функции
func main() { fmt.Println("1 + 2 =", add(1, 2)) }
func add(a int, b int) int { return a + b }
Функции
func main() { s, p := calculate(1, 2) fmt.Printf("1+2=%d, 1*2=%d", s, p) }
func calculate(a, b int) (int, int) { return a + b, a * b }
Функции
func main() { s, p := calculate(1, 2) fmt.Printf("1+2=%d, 1*2=%d", s, p) }
func calculate(a, b int) (int, int) { return a + b, a * b }
Функции
func main() { s, p := calculate(1, 2) fmt.Printf("1+2=%d, 1*2=%d", s, p) }
func calculate(a, b int) (s, p int) { s := a + b p := a * b return }
Функции
func main() { double := factory() double(14) }
func factory() func(a int) int { return func(a int) int { return a * 2 } }
Функции как значения
Массивыvar a [4]int a[0] = 1 i := a[0]
http://blog.golang.org/go-slices-usage-and-internals
arr := [2]string{"Foo", "Bar"}
arr := […]string{"Foo", "Bar"}
Слайсы Slicesa := []int{1, 2, 3} // [1 2 3]
Нет описания размерности
b := append(a, 4, 5) // [1 2 3 4 5]c := make(c, 3) // [0 0 0]d := b[1:3] // [2 3]e := b[:3] // [1 2 3]
Мапы Maps
monthdays := map[string]int{ "Jan": 31, "Feb": 28, "Mar": 31, "Apr": 30, "May": 31, "Jun": 30, "Jul": 31, "Aug": 31, "Sep": 30, "Oct": 31, "Nov": 30, "Dec": 31, }
for month, days := range monthdays { fmt.Println(month, days) }
Мапы Maps
monthdays := map[string]int{ "Jan": 31, "Feb": 28, "Mar": 31, "Apr": 30, "May": 31, "Jun": 30, "Jul": 31, "Aug": 31, "Sep": 30, "Oct": 31, "Nov": 30, "Dec": 31, }
for month, days := range monthdays { fmt.Println(month, days) }
Вот эта запятая - обязательна!
Мапы Maps
monthdays := map[string]int{ "Jan": 31, "Feb": 28, "Mar": 31, "Apr": 30, "May": 31, "Jun": 30, "Jul": 31, "Aug": 31, "Sep": 30, "Oct": 31, "Nov": 30, "Dec": 31, }
value, ok := monthdays["Jan"] fmt.Println(value) // 31 fmt.Println(ok) // true
Указатели
var p *int
i := 42 p = &i fmt.Println(*p) *p = 21 fmt.Println(i)
Нет арифметики указателей
Методыtype Vertex struct { X int Y int }
func (v Vertex) Total() int { return v.X + v.Y }
v := Vertex{1, 2} v.Total()
Интерфейсы
type Entity interface { Total() int }
Vertex реализует Entity
func (v Vertex) Total() int { return v.X + v.Y }
Интерфейсы
func foo(x interface{}) int { x.(Vertex).Total() }
panic: interface conversion: interface is main.Vertex2, not main.Vertex
goroutine 1 [running]: main.main() main.go:25 +0xcd exit status 2
foo(Vertex2{1,2})
Го-рутины
foo(Vertex2{1,2})
go foo(Vertex2{1,2})
Обычный вызов функции
Функция вызвана как го-рутина
func ready(w string, sec int) { time.Sleep(time.Duration(sec) * time.Second) fmt.Println(w, "is ready!") }
func main() { go ready("Tea", 2) go ready("Coffee", 1) fmt.Println("I'm waiting") time.Sleep(5 * time.Second) }
I’m waiting Coffee is ready Tea is ready
Каналыci := make(chan int) cs := make(chan string) cf := make(chan interface{})
ci <- 1 ← послать 1 в канал ci i := <-ci ← принять int из канала ci
var c chan int
func ready(w string, sec int) { time.Sleep(time.Duration(sec) * time.Second) fmt.Println(w, "is ready!”) с <-‐ 1 }
func main() { go ready("Tea", 2) go ready("Coffee", 1) fmt.Println("I'm waiting") <-‐c <-‐c }
var done = make(chan bool) var msgs = make(chan int)
func produce() { for i := 0; i < 10; i++ { msgs <-‐ i } done <-‐ true }
func consume() { for { msg := <-‐msgs println(msg) } }
func main() { go produce() go consume() <-‐ done }
var done = make(chan bool) var msgs = make(chan int)
func produce() { for i := 0; i < 10; i++ { msgs <-‐ i } done <-‐ true }
func consume() { for { msg := <-‐msgs println(msg) } }
func main() { go produce() go consume() <-‐ done }
Запустить го-‐рутины
var done = make(chan bool) var msgs = make(chan int)
func produce() { for i := 0; i < 10; i++ { msgs <-‐ i } done <-‐ true }
func consume() { for { msg := <-‐msgs println(msg) } }
func main() { go produce() go consume() <-‐ done }
Высылаем значения
var done = make(chan bool) var msgs = make(chan int)
func produce() { for i := 0; i < 10; i++ { msgs <-‐ i } done <-‐ true }
func consume() { for { msg := <-‐msgs println(msg) } }
func main() { go produce() go consume() <-‐ done }
Получаем и выводим значения
var done = make(chan bool) var msgs = make(chan int)
func produce() { for i := 0; i < 10; i++ { msgs <-‐ i } done <-‐ true }
func consume() { for { msg := <-‐msgs println(msg) } }
func main() { go produce() go consume() <-‐ done }
Готово!
Рабочее окружение
https://golang.org/doc/code.html#Workspaces
Инструментарий
• go (version, build, test, get, install, …)
• gofmt
• godoc
• Редакторы (vim, atom, IntelliJ IDEA)
Чего не хватает?
Отладчик Плагин для IntelliJ IDEA - в разработке
Возможна работа с GDB, но лучше сразу умереть
Менеджер зависимостей Много разных решений, все кривые
-vendor в 1.5
Кросс-компиляция
http://dave.cheney.net/2015/03/03/cross-compilation-just-got-a-whole-lot-better-in-go-1-5
env GOOS=linux GOARCH=386 go build hello.go
1. Собрал на Mac OS X для Linux
2. Запустил бинарник без дополнительных библиотек на Linux
Тестированиеpackage math
func Add(a, b int) int { return a + b } package math
import "testing"
func TestAdd(t *testing.T){ if Add(1, 3) != 4 { t.Error("Expecting 4") } }
Тестированиеpackage math
func Add(a, b int) int { return a + b } package math
import "testing"
func TestAdd(t *testing.T){ if Add(1, 3) != 4 { t.Error("Expecting 4") } }
/usr/local/go/bin/go test -‐v ./... -‐run ^TestAdd$ Testing started at 03:35 ... ? _/Users/anton/work-‐src/mygo [no test files]PASS ok _/Users/anton/work-‐src/mygo/math 0.007s
“У меня вот другой вопрос - а опердени на Go писать то уже можно или им только стартапы да уставшие
программисты балуются ?”
Вопрос на миллион долларов
— Евгений Холодков Профессионально разрабатывает опердени уже много лет
Оперденьpackage main
import "net/http"
func main() { panic(http.ListenAndServe(":8080", http.FileServer(http.Dir(".")))) }
Ресурсы
http://www.miek.nl/downloads/Go/Learning-Go-latest.pdfhttps://tour.golang.org
http://blog.golang.orghttp://golangshow.comhttp://4gophers.ru
https://www.youtube.com/playlist?list=PLMW8Xq7bXrG58Qk-9QSy2HRh2WVeIrs7e
https://www.youtube.com/channel/UCx9QVEApa5BKLw9r8cnOFEA
Gopher Academy:
dotGo:
@antonarhipovhttp://www.slideshare.net/arhan https://speakerdeck.com/antonarhipov