273_尚硅谷_管道的关闭和遍历
1.练习题目
package main
import (
"fmt"
"math/rand"
"time"
)
// 1) 创建一个 Person 结构体 [Name, Age, Address]
// 2) 使用 rand 方法配合随机创建 10个 Person 实例, 并放入到 channel 中
// 3) 遍历 channel, 将各个Person 实例的信息显示在终端
// 1) 创建 Person 结构体 [Name, Age, Address]
type Person struct {
Name string
Age int
Address string
}
// 随机数据池
var (
firstNames = []string{"张", "王", "李", "赵", "刘", "陈", "周", "吴", "郑", "孙"}
lastNames = []string{"伟", "强", "芳", "娜", "敏", "涛", "军", "静", "杰", "磊"}
cities = []string{"北京", "上海", "广州", "深圳", "成都", "武汉", "西安", "杭州", "南京", "重庆"}
streets = []string{"中山路", "解放路", "人民路", "建设路", "和平路", "新华路", "青年路", "文化路"}
)
// 生成随机人名
func randomName() string {
return firstNames[rand.Intn(len(firstNames))] + lastNames[rand.Intn(len(lastNames))]
}
// 生成随机地址
func randomAddress() string {
city := cities[rand.Intn(len(cities))]
street := streets[rand.Intn(len(streets))]
number := rand.Intn(300) + 1
return fmt.Sprintf("%s%s%d号", city, street, number)
}
// 生成随机Person
func generateRandomPerson() Person {
return Person{
Name: randomName(),
Age: rand.Intn(43) + 18, // 18-60岁
Address: randomAddress(),
}
}
func main() {
// 初始化随机种子
rand.Seed(time.Now().UnixNano())
// 2) 创建channel,使用缓冲channel
personChan := make(chan Person, 10)
// 生成10个随机Person并放入channel
fmt.Println("正在生成10个随机Person并放入channel...")
fmt.Println("====================================")
for i := 1; i <= 10; i++ {
person := generateRandomPerson()
personChan <- person
fmt.Printf("已将第%d个Person放入channel: %s, %d岁, %s\n",
i, person.Name, person.Age, person.Address)
}
// 关闭channel
close(personChan)
fmt.Println("\n所有Person已放入channel,现在从channel中读取:")
fmt.Println("====================================")
// 3) 遍历 channel, 将各个Person 实例的信息显示在终端
count := 1
for person := range personChan {
fmt.Printf("读取第%d个Person: 姓名: %s, 年龄: %d, 地址: %s\n",
count, person.Name, person.Age, person.Address)
count++
}
// 验证channel状态
if _, ok := <-personChan; !ok {
fmt.Println("\nchannel已关闭,读取完成")
}
}
2.放入两个数据进入管道 intChan, 执行close(chan_name)后,管道不可以再写入数据,只能读
package main
import "fmt"
// todo channel 的关闭
func main() {
intChan := make(chan int, 3)
intChan <- 100
intChan <- 200
// * 放入两个数据进入管道 intChan, 执行close(chan_name)后,管道不可以再写入数据,只能读
fmt.Printf("=============== 放入两个数据进入管道 intChan, 执行close(chan_name)后,管道不可以再写入数据,只能读 ===============\n")
close(intChan)
// * 关闭管道后, 再次尝试写入数据
intChan <- 300
fmt.Println("ok")
}
3.放入两个数据进入管道 intChan, 执行close(chan_name)后,管道不可以再写入数据,只能读
package main
import "fmt"
// todo channel 的关闭
func main() {
intChan := make(chan int, 3)
intChan <- 100
intChan <- 200
// * 放入两个数据进入管道 intChan, 执行close(chan_name)后,管道不可以再写入数据,只能读
fmt.Printf("=============== 放入两个数据进入管道 intChan, 执行close(chan_name)后,管道不可以再写入数据,只能读 ===============\n")
close(intChan)
// * 关闭管道后, 再次尝试写入数据
// intChan <- 300
fmt.Println("ok")
n1 := <-intChan
n2 := <-intChan
fmt.Printf("n1= %v, n2= %v", n1, n2)
}
4.channel 的遍历
package main
import "fmt"
// todo channel 的遍历
// channel 支持 for--range的方式进行遍历, 注意两个细节
// 1) 在遍历时, 如果channel没有关闭, 则会出现deadlock的错误
// 2) 在遍历时, 如果channel已经关闭,则会正常遍历数据,遍历完后,就会退出遍历
func main() {
intChan := make(chan int, 3)
intChan <- 100
intChan <- 200
// * 放入两个数据进入管道 intChan, 执行close(chan_name)后,管道不可以再写入数据,只能读
fmt.Printf("=============== 放入两个数据进入管道 intChan, 执行close(chan_name)后,管道不可以再写入数据,只能读 ===============\n")
close(intChan)
// * 关闭管道后, 再次尝试写入数据
// intChan <- 300
fmt.Println("ok")
// * 遍历管道
intChan2 := make(chan int, 100)
for i := 0; i < 100; i++ {
intChan2 <- i * 2 // 放入100 个数据到管道
}
// ! 在遍历前, 如果channel没有关闭,虽然可以正常取出数据,但是会出现deadlock的错误
// ! 所以在管道写入完成后,必须执行Close(channel_name)关闭管道
close(intChan2)
// 遍历, 必须要用 for___range形式遍历channel
for item := range intChan2 {
fmt.Printf("%v\n", item)
}
}
浙公网安备 33010602011771号