package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
c := make(chan int)
for i := 0; i < 5; i++ {
worker := &Worker{id: i}
go worker.process(c)
}
for {
c <- rand.Int()
time.Sleep(time.Millisecond * 500)
}
}
type Worker struct {
id int
}
func (w *Worker) process(c chan int) {
for {
data := <-c
fmt.Printf("worker %d got %d\n", w.id, data)
}
}
输出:
$ go run test.go
worker 4 got 5577006791947779410
worker 1 got 8674665223082153551
worker 2 got 6129484611666145821
worker 3 got 4037200794235010051
worker 0 got 3916589616287113937
worker 4 got 6334824724549167320
worker 1 got 605394647632969758
...
我们不知道哪个 worker
将获得数据。我们所知道的是,Go 语言确保,往一个通道发送数据时,仅有一个单独的接收器可以接收。
注意:通道是唯一共享的状态,通过通道,可以安全的,并发发送和接收数据。通道提供了我们需要的所有同步代码,并且也确保,在任意的特定时刻,只有一个 Go 协程,可以访问数据的特定部分。
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
c := make(chan int)
for i := 0; i < 5; i++ {
worker := &Worker{id: i}
go worker.process(c)
}
for {
select {
case c <- rand.Int():
case <-time.After(time.Millisecond * 100):
fmt.Println("timed out")
}
time.Sleep(time.Millisecond * 50)
}
}
type Worker struct {
id int
}
func (w *Worker) process(c chan int) {
for {
data := <-c
fmt.Printf("worker %d got %d\n", w.id, data)
time.Sleep(time.Second * 2)
}
}
select
工作机制:
default
分之被执行default
分支,select
将阻塞package main
import "fmt"
func main() {
scores := make([]int, 0, 5)
c := cap(scores)
fmt.Println(c)
for i := 0; i < 25; i++ {
scores = append(scores, i)
if cap(scores) != c {
c = cap(scores)
fmt.Println(c)
}
}
}
$ go run test.go
5
10
20
40
package main
import "fmt"
func main() {
scores := make([]int, 5)
fmt.Println(scores, len(scores), cap(scores))
scores = append(scores, 9332)
fmt.Println(scores, len(scores), cap(scores))
}
$ go run test.go
[0 0 0 0 0] 5 5
[0 0 0 0 0 9332] 6 10
package main
import "fmt"
func main() {
scores := []int{1, 2, 3, 4, 5}
scores = removeAtIndex(scores, 2)
fmt.Println(scores)
}
func removeAtIndex(source []int, index int) []int {
lastIndex := len(source) - 1
source[index], source[lastIndex] = source[lastIndex], source[index]
return source[:lastIndex]
}
$ go run test.go
[1 2 5 4]
package main
import (
"fmt"
"math/rand"
"sort"
)
func main() {
scores := make([]int, 100)
for i := 0; i < 100; i++ {
scores[i] = int(rand.Int31n(2000))
}
sort.Ints(scores)
fmt.Println(scores)
worst1 := make([]int, 5)
copy(worst1, scores[:5])
fmt.Println(worst1)
worst2 := make([]int, 5)
copy(worst2[2:4], scores[:5])
fmt.Println(worst2)
worst3 := make([]int, 5)
copy(worst3, scores[:10])
fmt.Println(worst3)
// panic: runtime error: slice bounds out of range
// worst4 := make([]int, 5)
// copy(worst4[:10], scores[:10])
// fmt.Println(worst4)
}
$ go run copyDemo.go
[2 47 59 59 78 81 81 147 156 159 162 199 205 258 266 287 324 376 408 413 420 425 433 451 456 495 503 510 511 538 540 546 552 563 605 623 631 643 694 705 728 783 790 831 878 888 888 953 1000 1002 1015 1026 1033 1089 1090 1094 1106 1107 1133 1137 1189 1194 1202 1211 1237 1241 1274 1300 1318 1336 1353 1355 1356 1387 1429 1445 1447 1463 1466 1485 1528 1541 1561 1563 1577 1598 1703 1718 1721 1737 1746 1828 1843 1847 1887 1891 1940 1947 1957 1996]
[2 47 59 59 78]
[0 0 2 47 0]
[2 47 59 59 78]
package main
import "fmt"
var c1 = make(chan int, 1)
var c2 = make(chan string, 1)
func main() {
c1 <- 1
c2 <- "hello"
select {
case v1 := <-c1:
fmt.Println(v1)
case v2 := <-c2:
panic(v2)
}
}
可能执行到 v1,也可能执行到 v2。
package main
import (
"fmt"
)
type student struct {
Name string
Age int
}
func main() {
m := pase_map()
for k, v := range m {
fmt.Printf("key = %s,value =%v\n", k, v)
}
}
func pase_map() map[string]*student {
m := make(map[string]*student)
stu := []student{
{"joy", 12}, {"lei", 14}, {"jian", 18},
}
for _, v := range stu {
m[v.Name] = &v
}
return m
}
$ go run test.go
key = joy,value =&{jian 18}
key = lei,value =&{jian 18}
key = jian,value =&{jian 18}
说明 v 一直都是同一个变量。
package main
import (
"fmt"
)
type student struct {
Name string
Age int
}
func main() {
m := pase_map()
for k, v := range m {
fmt.Printf("key = %s,value =%v\n", k, v)
}
}
func pase_map() map[string]*student {
m := make(map[string]*student)
stu := []student{
{"joy", 12}, {"lei", 14}, {"jian", 18},
}
for k, v := range stu {
m[v.Name] = &stu[k]
}
return m
}
$ go run test.go
key = joy,value =&{joy 12}
key = lei,value =&{lei 14}
key = jian,value =&{jian 18}
package main
import (
"fmt"
"time"
)
func main() {
for i := 1; i <= 10; i++ {
go func(i int) {
fmt.Println(2*i - 1)
}(i)
}
for i := 1; i <= 10; i++ {
go func(i int) {
fmt.Println(2 * i)
}(i)
}
time.Sleep(3 * time.Second)
}
package main
import (
"fmt"
)
func main() {
a := make(chan int)
b := make(chan int)
exit := make(chan int)
go func() {
for i := 1; i <= 20; i++ {
fmt.Println(<-a)
i++
b <- i
}
}()
go func() {
for i := 0; i < 20; i++ {
i++
a <- i
fmt.Println(<-b)
}
close(exit)
}()
<-exit
}
ctrl + shift + 鼠标右键