Введение

Лекция 1

Максим Иванов

Добро пожаловать

2

Ссылки

3

Что нас ждёт?

4

Hello world

package main

import "fmt"

func main() {
    fmt.Println("Hello, 世界")
}
5

Go

Concurrent

Garbage Collected

Systems

Language

6

История

7

Зачем Go сегодня

8

Скорость разработки

9

Цели Go

10

Compilation Demo

# 1 пакет за 200 ms
time go build -a -v math

# 84 пакета за 7 секунд
time go build -a -v github.com/golang/protobuf/...
11

Принципы дизайна

Небольшое число ортогональных фич.

Простой синтаксис (понятный для людей и машин).

Простая система типов. Объектно ориентированный, но без наследования.

12

Hello World

package main

import "fmt"

func main() {
    fmt.Println("Hello, 世界")
}
13

echo

package main

import (
    "fmt"
    "os"
)

func main() {
    var s, sep string
    for i := 1; i < len(os.Args); i++ {
        s += sep + os.Args[i]
        sep = " "
    }
    fmt.Println(s)
}
14

For loop

Полная форма.

for initialization; condition; post {
    // statements
}

Как while.

for condition {
    // statements
}

Бесконечный цикл.

for {
    // statements
}
15

echo2

package main

import (
    "fmt"
    "os"
)

func main() {
    s, sep := "", ""
    for _, arg := range os.Args[1:] {
        s += sep + arg
        sep = " "
    }
    fmt.Println(s)
}
16

Range

Полная форма.

for i, v := range slice {
    // ...
}

Только индекс.

for i := range slice {
    // ...
}

Индекс не используется.

for _, v := range slice {
    // ...
}
17

Массивы

var arr [3]int        // [0 0 0]
a := [3]int{1, 2, 3}  // len=3
b := [...]int{1, 2, 3} // длина по литералу

// Индексация и длина
_ = a[0]
_ = len(a)

// Массив — значение (копируется)
a2 := a
a2[0] = 99
fmt.Println(a) // [1 2 3]
fmt.Println(a2) // [99 2 3]
18

Слайсы

var a []int          // nil, len=0, cap=0
b := []int{}         // пустой, len=0, cap=0 (но не nil)
c := []int{1, 2, 3}  // len=3, cap=3
d := make([]int, 2)  // len=2, cap=2 -> [0 0]
e := make([]int, 2, 5) // len=2, cap=5

nums := []int{0, 1, 2, 3, 4, 5}
sub := nums[1:4]        // [1 2 3]
sub[0] = 99             // меняет nums[1]

s := []int{1, 2}
s = append(s, 3)
s = append(s, 4, 5)

a2 := []int{1, 2}
b2 := []int{3, 4}
a2 = append(a2, b2...) // [1 2 3 4]
arr := []int{1, 2, 3}
arr2 := arr
arr2[0] = 99
fmt.Println(arr)  // [99 2 3]
fmt.Println(arr2) // [99 2 3]
19

Переменные

s := ""
var s string
var s = ""
var s string = ""
20

uniq

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    counts := make(map[string]int)
    input := bufio.NewScanner(os.Stdin)
    for input.Scan() {
        counts[input.Text()]++
    }

    // NOTE: ignoring potential errors from input.Err()
    for line, n := range counts {
        fmt.Printf("%d\t%s\n", n, line)
    }
}
21

Printf

%d         decimal integer
%x, %o, %b integer in hexadecimal, octal, binary
%f, %g, %e floating-point number: 3.141593 3.141592653589793 3.141593e+00
%t         boolean: true or false
%c         rune (Unicode code point)
%s         string
%q         quoted string "abc" or rune 'c'
%v         any value in a natural format
%T         type of any value
%%         literal percent sign (no operand)

Функции форматирования заканчиваются на f. fmt.Errorf, log.Printf.

22

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

func load() error {
    if err := step1(); err != nil {
        return err
    }
    if err := step2(); err != nil {
        return err
    }
    return nil
}
if err != nil {
    return fmt.Errorf("read config: %w", err)
}
if errors.Is(err, os.ErrNotExist) {
    // специфичная реакция
}
var target *json.SyntaxError
if errors.As(err, &target) {
    fmt.Printf("syntax error at byte offset %d: %v\n", target.Offset, target)
}
23

urlfetch

func main() {
    for _, url := range os.Args[1:] {
        resp, err := http.Get(url)
        if err != nil {
            fmt.Fprintf(os.Stderr, "fetch: %v\n", err)
            os.Exit(1)
        }
        b, err := io.ReadAll(resp.Body)
        resp.Body.Close()
        if err != nil {
            fmt.Fprintf(os.Stderr, "fetch: reading %s: %v\n", url, err)
            os.Exit(1)
        }
        fmt.Printf("%s", b)
    }
}
24

fetchall

func main() {
    start := time.Now()
    ch := make(chan string)
    for _, url := range os.Args[1:] {
        go fetch(url, ch) // start a goroutine
    }
    for range os.Args[1:] {
        fmt.Println(<-ch) // receive from channel ch
    }
    fmt.Printf("%.2fs elapsed\n", time.Since(start).Seconds())
}
25

fetchall

func fetch(url string, ch chan<- string) {
    start := time.Now()
    resp, err := http.Get(url)
    if err != nil {
        ch <- fmt.Sprint(err) // send to channel ch
        return
    }
    defer resp.Body.Close() // don't leak resources

    nbytes, err := io.Copy(io.Discard, resp.Body)
    if err != nil {
        ch <- fmt.Sprintf("while reading %s: %v", url, err)
        return
    }
    secs := time.Since(start).Seconds()
    ch <- fmt.Sprintf("%.2fs %7d %s", secs, nbytes, url)
}
26

webserver

package main

import (
    "fmt"
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/", handler) // each request calls handler
    log.Fatal(http.ListenAndServe("localhost:8000", nil))
}

// handler echoes the Path component of the request URL r.
func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "URL.Path = %q\n", r.URL.Path)
}
27

counter

var (
    counter int
    mu      sync.Mutex
)

func main() {
    http.HandleFunc("/", handler)
    log.Fatal(http.ListenAndServe("localhost:8000", nil))
}

func handler(w http.ResponseWriter, r *http.Request) {
    var i int

    mu.Lock()
    i = counter
    counter++
    mu.Unlock()

    fmt.Fprintf(w, "counter = %d\n", i)
}
28

switch

switch coinflip() {
case "heads":
    heads++
case "tails":
    tails++
default:
    fmt.Println("landed on edge!")
}

tagless switch.

func Signum(x int) int {
    switch {
    case x > 0:
        return +1
    default:
        return 0
    case x < 0:
        return -1
    }
}
29

Other

Struct

type Point struct {
    X, Y int
}
var p Point

Pointers

var s string
p := &s
s2 := *p

var p Point
p.X = 1

var pp *Point
pp.X = 1
30

The Go Programming Language

Всего 400 страниц.

31

Документация

32

Семинар

33

Thank you

Максим Иванов

Use the left and right arrow keys or click the left and right edges of the page to navigate between slides.
(Press 'H' or navigate to hide this message.)