package main
import "fmt"
func main() {
ch := make(chan int)
go func() {
for i := 1; i <= 3; i++ {
ch <- i * i
}
close(ch)
}()
for v := range ch {
fmt.Println(v)
}
}
package main
import "fmt"
func main() {
for i := 1; i <= 15; i++ {
switch {
case i%15 == 0:
fmt.Println("FizzBuzz")
case i%3 == 0:
fmt.Println("Fizz")
case i%5 == 0:
fmt.Println("Buzz")
default:
fmt.Println(i)
}
}
}
切片和 append
越长越大时 len 和 cap 怎么变;可视化里看得见背后的数组。
package main
import "fmt"
func main() {
var s []int
for i := 1; i <= 5; i++ {
s = append(s, i*i)
fmt.Println(s, len(s), cap(s))
}
}
map 计数
数每个单词出现了几次。
package main
import (
"fmt"
"sort"
"strings"
)
func main() {
text := "go is fun and go is fast"
count := map[string]int{}
for _, w := range strings.Fields(text) {
count[w]++
}
keys := make([]string, 0, len(count))
for k := range count {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
fmt.Println(k, count[k])
}
}
结构体和方法
指针接收者改的是结构体本身。
package main
import "fmt"
type Account struct {
Owner string
Balance int
}
func (a *Account) Deposit(n int) {
a.Balance += n
}
func main() {
acc := Account{"Maya", 100}
acc.Deposit(50)
fmt.Println(acc.Owner, acc.Balance)
}
接口
不同的形状,同一个 Area 方法。
package main
import (
"fmt"
"math"
)
type Shape interface {
Area() float64
}
type Rect struct{ W, H float64 }
type Circle struct{ R float64 }
func (r Rect) Area() float64 { return r.W * r.H }
func (c Circle) Area() float64 { return math.Pi * c.R * c.R }
func main() {
shapes := []Shape{Rect{3, 4}, Circle{1}}
for _, s := range shapes {
fmt.Printf("%.2f\n", s.Area())
}
}
错误处理
函数返回一个值和一个 error。
package main
import (
"errors"
"fmt"
)
func divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}
func main() {
for _, b := range []int{2, 0} {
q, err := divide(10, b)
if err != nil {
fmt.Println("error:", err)
continue
}
fmt.Println(q)
}
}
闭包
一个记得自己计数的函数。
package main
import "fmt"
func counter() func() int {
n := 0
return func() int {
n++
return n
}
}
func main() {
next := counter()
fmt.Println(next(), next(), next())
}
goroutine 和 channel
一个 goroutine 发平方数,main 收。
package main
import "fmt"
func main() {
ch := make(chan int)
go func() {
for i := 1; i <= 3; i++ {
ch <- i * i
}
close(ch)
}()
for v := range ch {
fmt.Println(v)
}
}
等大家都做完
sync.WaitGroup 和 Mutex。
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
var mu sync.Mutex
total := 0
for i := 1; i <= 3; i++ {
wg.Add(1)
go func(n int) {
defer wg.Done()
mu.Lock()
total += n
mu.Unlock()
}(i)
}
wg.Wait()
fmt.Println("total", total)
}
select 和超时
等哪个先来就用哪个。
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan string)
go func() {
time.Sleep(50 * time.Millisecond)
ch <- "done"
}()
select {
case r := <-ch:
fmt.Println(r)
case <-time.After(time.Second):
fmt.Println("too slow")
}
}
sort.Slice 排序
用比较函数按年龄排序。
package main
import (
"fmt"
"sort"
)
type Person struct {
Name string
Age int
}
func main() {
people := []Person{{"Ava", 31}, {"Ben", 25}, {"Cy", 40}}
sort.Slice(people, func(i, j int) bool {
return people[i].Age < people[j].Age
})
fmt.Println(people)
}
下标越界
Go 原话的 panic,以及出事的那一步。
package main
import "fmt"
func main() {
nums := []int{1, 2, 3}
for i := 0; i <= len(nums); i++ {
fmt.Println(nums[i])
}
}