Про язык программирования Go

Почему Go

  • Относительно простой (аля Python)
  • Статическая типизация
  • GC
  • Компиляция в статический бинарник
  • Отличная стандартная библиотека
  • Concurrency в основе языка

Почему Goлнца свет

Кто использует

  • Mail.Ru
  • Google (в том числе Youtube)
  • Docker
  • Dropbox
  • Canonical
  • GOV.UK
  • Другие

Hello World

package main

import (
    "fmt"
)

func main() {
    fmt.Println("Hello World")
}

Запуск

go build main.go
./main

Особенности

  • Организация разработки
  • Пакеты и их менеджмент
  • Обработка ошибок
  • defer
  • Структуры
  • Горутины (goroutines)
  • Каналы
  • Интерфейсы

Организация разработки

$GOROOT (install)

 

$GOPATH (workspace)

|

 -------- bin/

 -------- pkg/

|

 -------- src/

Пакеты

import "fmt"
import (
    "github.com/russross/blackfriday"
    "gopkg.in/russross/blackfriday.v1"
)
go get github.com/russross/blackfriday

Обработка ошибок

package main

import (
    "os"
    "strconv"
)

n, err := strconv.Atoi(os.Args[1])
if err != nil {
    println("not a valid number")
} else {
    println(n)
}

А также panic(), recover()

defer

package main

import(
    "os"
)

func main() {
    file, err := os.Open("a_file_to_read")
    if err != nil {
        println(err)
        return
    }
    defer file.Close()
    // read the file
}

Структуры

type Machine struct {
    Name    string
    Broken  bool
}

func (m *Machine) Crash() {
    m.Broken = true
}

Композиция

type Tank struct {
    *Machine
}

func (t *Tank) Crash() {
    t.Broken = false
}

Горутины (goroutines)

package main

import (
    "fmt"
    "time"
)

func main() {
    fmt.Println("start")
    go process("1")
    go process("2")
    go process("3")
    time.Sleep(time.Millisecond * 10) // WRONG!
    fmt.Println("done")
}

func process(input string) {
    fmt.Println(input)
}

Каналы

package main

import (
    "fmt"
)

func main() {
    done := make(chan bool)
    go process("1", done)
    go process("2", done)
    go process("3", done)
    <-done
    <-done
    <-done
}

func process(input string, done chan bool) {
    fmt.Println(input)
    done<-true 
}

Каналы

Отправка данных в канал:

 

Каналы с буфером:

CHANNEL <- DATA

Чтение из канала:

VAR := <- CHANNEL
ch := make(chan int, 100)

Каналы

for {
    select {
    case data := <-c:
        fmt.Println("worker got data")
    case <-time.After(time.Millisecond * 10):
        fmt.Println("Break time")
        time.Sleep(time.Second)
    }
}
select {
case v := <-ch1:
    fmt.Println("channel 1 sends", v)
case v := <-ch2:
    fmt.Println("channel 2 sends", v)
default: // optional
    fmt.Println("neither channel was ready")
}

С таймаутом

Интерфейсы

type Reader interface {
    Read(p []byte) (n int, err error)
}

type Writer interface {
    Write(p []byte) (n int, err error)
}

func Copy(dst Writer, src Reader) (written int64, err error)

Пустой интерфейс

func DoSomething(v interface{}) {
   // ...
}

Другие особенности

  • Строгая обратная совместимость новых версий
  • Кросс-компиляция
  • Зачаточная поддержка Android
  • Concurrent GC в будущем

Ссылки

Не забыть показать http/2.0

Made with Slides.com