标签:service 选择 printf 地址 协程 编译器 读取数据 导致 www
if num,ok := <-ch;ok{
//如果ok为false,定是管道已经关闭了
}
package main
import (
"fmt"
)
func send(out chan<- int) {
out <- 89
close(out)
}
func recv(in <-chan int) {
n := <-in
fmt.Println("读到", n)
}
func main() {
ch := make(chan int)
go func() {
send(ch)
}()
recv(ch)
}
定义/声明
var intChan chan int //intChan用于存放int数据
var mapChan chan map[int]string //mapChan用于存放map[int]string类型
var perChan chan Person
var perChan2 chan *Person
package main
import "fmt"
func main(){
var intChan chan int
intChan = make(chan int, 3)
fmt.Printf("intChan的值=%v intChan本身的地址=%p\n",intChan, &intChan)
//intChan的值=0xc00007a080 intChan本身的地址=0xc000006028
intChan<- 10
num:=211
//向管道写入数据
intChan<- num
//看看管道的长度和cap(容量)
fmt.Printf("channel len=%v cap=%v \n",len(intChan),cap(intChan))
//从管道中读取数据
var num2 int
num2 = <-intChan
fmt.Println("num2=", num2)
fmt.Printf("channel len=%v cap=%v \n",len(intChan),cap(intChan))
<-intChan //直接取值不接收
//在没有下,取完后继续取回报错
}
package main
import "fmt"
type Cat struct{ Name string }
func main() {
var catChan chan interface{}
catChan = make(chan interface{}, 10)
cat := Cat{"小花猫"}
catChan <- cat
newCat := <-catChan //newCat.Name是错的编译的时候编译器会认为newCat是一个接口
c := newCat.(Cat) //使用类型断言转换之后可以正常使用
fmt.Println(c.Name) //小花猫
}
package main
import "fmt"
func main(){
intChan := make(chan int, 3)
intChan<- 100
intChan<- 200
close(intChan) //close channel此时只能读不能写
}
package main
import "fmt"
func main() {
intChan := make(chan int, 100)
for i := 0; i < 100; i++ {
intChan <- i * 2 //放入100个数据到管段
}
//遍历管道要使用fo range的方式去遍历,普通遍历不可以,因为每取一次容量会减少
close(intChan) // 在遍历时,如果管道没有关闭,则会出现deadlock的错误
for v := range intChan {
fmt.Println("v=", v)
}
}
intChan := make(chan int, 100)
for i := 0; i < 100; i++ {
intChan <- i * 2 //放入100个数据到管段
}
if v, ok := <- intChan;ok{ //成功取到值ok为true否则为false
fmt.Print(v)
}
如果编译器运行,发现一个管道只有写,没有读,则该管道会阻塞
写管道和读管道的频率不一致,无所谓。
for{
if v, isClose := <- intChan;isClose{ //通过这种方式判断管道已经关闭
break
}
}
var wChan chan <-int
var rChan <-chan int
看下例子
func service1(ch chan string) {
time.Sleep(2 * time.Second)
ch <- "from service1"
}
func service2(ch chan string) {
time.Sleep(1 * time.Second)
ch <- "from service2"
}
func main() {
ch1 := make(chan string)
ch2 := make(chan string)
go service1(ch1)
go service2(ch2)
select { // 会发送阻塞
case s1 := <-ch1:
fmt.Println(s1)
case s2 := <-ch2:
fmt.Println(s2)
}
}
func service1(ch chan string) {
//time.Sleep(2 * time.Second)
ch <- "from service1"
}
func service2(ch chan string) {
//time.Sleep(1 * time.Second)
ch <- "from service2"
}
func main() {
ch1 := make(chan string)
ch2 := make(chan string)
go service1(ch1)
go service2(ch2)
time.Sleep(2*time.Second)
select {
case s1 := <-ch1:
fmt.Println(s1)
case s2 := <-ch2:
fmt.Println(s2)
}
}
//我们把函数里的延时注释掉,主函数 select 之前加 2s 的延时以等待两个信道的数据准备好,select 会随机选取其中一个 case 执行,所以输出也是随机的。
func service1(ch chan string) {
ch <- "from service1"
}
func service2(ch chan string) {
ch <- "from service2"
}
func main() {
ch1 := make(chan string)
ch2 := make(chan string)
go service1(ch1)
go service2(ch2)
select { // ch1 ch2 都还没有准备好,直接执行 default 分支
case s1 := <-ch1:
fmt.Println(s1)
case s2 := <-ch2:
fmt.Println(s2)
default:
fmt.Println("no case ok")
}
}
有时候,我们不希望立即执行 default 语句,而是希望等待一段时间,若这个时间段内还没有可操作的信道,则执行规定的语句。可以在 case 语句后面设置超时时间。
func service1(ch chan string) {
time.Sleep(5 * time.Second)
ch <- "from service1"
}
func service2(ch chan string) {
time.Sleep(3 * time.Second)
ch <- "from service2"
}
func main() {
ch1 := make(chan string)
ch2 := make(chan string)
go service1(ch1)
go service2(ch2)
select { // 会发送阻塞
case s1 := <-ch1:
fmt.Println(s1)
case s2 := <-ch2:
fmt.Println(s2)
case <-time.After(2*time.Second): // 等待 2s
fmt.Println("no case ok")
}
}
func test(){
defer func(){
if err := recover(); err!=nil{
fmt.Println("test() 发生错误",err)
}
}()
var myMap map[int]string
myMap[0] = "golang" //error 这里没有make直接使用map会抛出异常
}
标签:service 选择 printf 地址 协程 编译器 读取数据 导致 www
原文地址:https://www.cnblogs.com/hualou/p/12069873.html