273_尚硅谷_管道的关闭和遍历

1.练习题目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)后,管道不可以再写入数据,只能读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)后,管道不可以再写入数据,只能读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 的遍历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)
	}

}

  

posted on 2026-03-04 17:56  与太阳肩并肩  阅读(1)  评论(0)    收藏  举报

导航