Введение
Лекция 1
Максим Иванов
Максим Иванов
package main import "fmt" func main() { fmt.Println("Hello, 世界") }
Concurrent
Garbage Collected
Systems
Language
6# 1 пакет за 200 ms time go build -a -v math # 84 пакета за 7 секунд time go build -a -v github.com/golang/protobuf/...
Небольшое число ортогональных фич.
Простой синтаксис (понятный для людей и машин).
Простая система типов. Объектно ориентированный, но без наследования.
12package main import "fmt" func main() { fmt.Println("Hello, 世界") }
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) }
Полная форма.
for initialization; condition; post {
// statements
}Как while.
for condition {
// statements
}Бесконечный цикл.
for {
// statements
}package main import ( "fmt" "os" ) func main() { s, sep := "", "" for _, arg := range os.Args[1:] { s += sep + arg sep = " " } fmt.Println(s) }
Полная форма.
for i, v := range slice {
// ...
}Только индекс.
for i := range slice {
// ...
}Индекс не используется.
for _, v := range slice {
// ...
}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]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]s := "" var s string var s = "" var s string = ""
Почему тип пишется после названия переменной
20package 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) } }
%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.
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)
}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) } }
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()) }
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) }
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) }
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) }
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
}
}Struct
type Point struct {
X, Y int
}
var p PointPointers
var s string p := &s s2 := *p var p Point p.X = 1 var pp *Point pp.X = 1
Всего 400 страниц.
31Документация стандартной библиотеки
32Максим Иванов