funcdescribe(i interface{}) { fmt.Printf("(%v, %T)\n", i, i) }
//类型断言 //类型断言 提供了访问接口值底层具体值的方式 //t := i.(T) 该语句断言接口值 i 保存了具体类型 T ,并将其底层类型为 T 的值赋予变量 t //若 i 并未保存 T 类型的值,该语句就会触发一个panic
//为了 判断 一个接口值是否保存了一个特定的类型, 类型断言可返回两个值:其底层值以及一个报告断言是否成功的布尔值 //t, ok := i.(T) 若 i 保存了一个 T ,那么 t 将会是其底层值,而 ok 为 true //否则, ok 将为 false 而 t 将为 T 类型的零值,程序并不会产生恐慌
funcappendString(bs []string, b byte) []string { var a byte var s int for i := 0; i < 8; i++ { a = b b <<= 1 b >>= 1 switch a { case b: s += 0 default: temp := 1 for j := 0; j < 7 - i; j++ { temp = temp*2 } s += temp }
b <<= 1 }
bs = append(bs, strconv.Itoa(s)) return bs }
funcBytesToString(bs []byte)string { l := len(bs) buf := make([]string, 0, l) for i := 0; i < l; i++ { buf = appendString(buf, bs[i]) } return strings.Join(buf, ".") }
//fatal error: all goroutines are asleep - deadlock! //goroutine 1 [chan send]: ... exit status 2 //ch <- 3
fmt.Println(<-ch) fmt.Println(<-ch) }
//range 和 close //send to channel, receive from channel //sender可通过 close 关闭一个信道来表示没有需要发送的值了。receiver可以通过为接收表达式分配第二个参数来测试信道是否被关闭: //若没有值可以接收且信道已被关闭,那么在执行完 v, ok := <-ch 之后 ok 会被设置为 false //只有发送者才能关闭信道,而接收者不能。向一个已经关闭的信道发送数据会引发 panic //信道与文件不同,通常情况下无需关闭它们。只有在必须告诉接收者不再有值需要发送的时候才有必要关闭,例如终止一个 range 循环 //若在信道关闭后从中接收数据,接收者就会收到该信道返回的零值
package main
import ( "fmt" )
funcfibonacci(n int, c chanint) { x, y := 0, 1 for i := 0; i < n; i++ { c <- x x, y = y, x+y } close(c) }
funcmain() { c := make(chanint, 10) go fibonacci(cap(c), c) for i := range c { fmt.Println(i) } }
//select 语句 package main
import ( "fmt" )
funcfibonacci(c, quit chanint) { x, y := 0, 1 for { select { case c <- x: fmt.Println("send...", x) x, y = y, x+y case <-quit: fmt.Println("quit") return default: fmt.Println("wait......") } } }
funcmain() { c := make(chanint) quit := make(chanint) //使用 go 在一个新的 goroutine 中执行代码,此函数中的for循环不一定在主线程调用fibonacci(c, quit)之前就会执行; //因此,可能会首先打印wait......,等待sender和receiver准备好 gofunc() { for i := 0; i < 10; i++ { fmt.Println("receive...", <-c) } quit <- 0 }() fibonacci(c, quit) }
//sync.Mutex package main
import ( "fmt" "sync" //"time" )
// SafeCounter 的并发使用是安全的。 type SafeCounter struct { v map[string]int mux sync.Mutex }
//默认情况下,发送和接收操作在另一端准备好之前都会阻塞。这使得 Go 程可以在没有显式的锁或竞态变量的情况下进行同步 //goroutine阻塞后,在函数操作执行之前main线程就已完成并退出 //goroutine背后的系统知识: http://www.sizeofvoid.net/goroutine-under-the-hood/ //Concurrency is not Parallelism: https://talks.golang.org/2012/waza.slide#1
// Send the sequence 2, 3, 4, ... to channel 'ch'. funcGenerate(ch chan<- int) { for i := 2; ; i++ { ch <- i // Send 'i' to channel 'ch'. print("---", i, "---") } }
// Copy the values from channel 'in' to channel 'out', // removing those divisible by 'prime'. funcFilter(in <-chanint, out chan<- int, prime int) { for { i := <-in // Receive value from 'in'. if i%prime != 0 { print("+++", i, "+++") out <- i // Send 'i' to 'out'. } } }
// The prime sieve: Daisy-chain Filter processes. funcmain() { ch := make(chanint) // Create a new channel. go Generate(ch) // Launch Generate goroutine. for i := 0; i < 10; i++ { prime := <-ch fmt.Println(prime) ch1 := make(chanint) go Filter(ch, ch1, prime) ch = ch1 } }