《Go语言圣经》关闭一个channel

《Go语言圣经》关闭一个channel

func main() {
    naturals := make(chan int)
    squares := make(chan int)

    // Counter
    go func() {
        for x := 0; x < 100; x++ {
            naturals <- x
        }
        close(naturals)
    }()

    // Squarer
    go func() {
        for x := range naturals {
            squares <- x * x
        }
        close(squares)
    }()

    // Printer (in main goroutine)
    for x := range squares {
        fmt.Println(x)
    }
}

  • 在Go语言中,当一个channel被关闭后,已经发送到该channel中的数据仍然可以被正常接收,直到所有数据都被处理完毕。
  • 试图重复关闭一个channel将导致panic异常,试图关闭一个nil值的channel也将导致panic异常。关闭一个channels还会触发一个广播机制,

详细解释

在你的代码中:

  1. Counter协程naturals channel发送0到99的整数,然后关闭该channel
  2. Squarer协程使用for x := range naturals循环从naturals接收数据
  3. naturals被关闭时
    • 已经发送到naturals中的数据(0到99)仍然会被Squarer协程正常接收
    • for ... range循环会继续处理这些数据,直到所有数据都被处理完毕
    • 只有当所有数据都被接收后,for ... range循环才会退出

关键点

  • 关闭channel不会影响已发送的数据:关闭操作只是阻止后续的数据发送,不会影响已经在channel中的数据
  • for ... range循环会处理所有已发送的数据:无论channel是否关闭,循环都会继续执行,直到所有数据被接收
  • 关闭是一种信号:关闭channel是向接收方发送一个信号,表示"不会再有新数据了",但已有的数据仍然有效

验证代码

以下代码可以帮助你验证这个过程:

package main

import "fmt"

func main() {
    naturals := make(chan int)
    squares := make(chan int)

    // Counter
    go func() {
        for x := 0; x < 5; x++ {
            naturals <- x
            fmt.Println("Counter sent:", x)
            // 添加延迟以便观察执行顺序
            if x == 2 {
                close(naturals)
                fmt.Println("Counter closed naturals")
            }
        }
    }()

    // Squarer
    go func() {
        for x := range naturals {
            squares <- x * x
            fmt.Println("Squarer received:", x, "sending:", x*x)
        }
        close(squares)
        fmt.Println("Squarer closed squares")
    }()

    // Printer
    for x := range squares {
        fmt.Println("Printer received:", x)
    }
    fmt.Println("Done")
}

输出示例

Counter sent: 0
Squarer received: 0 sending: 0
Printer received: 0
Counter sent: 1
Squarer received: 1 sending: 1
Printer received: 1
Counter sent: 2
Squarer received: 2 sending: 4
Printer received: 4
Counter closed naturals
Counter sent: 3
Squarer received: 3 sending: 9
Printer received: 9
Counter sent: 4
Squarer received: 4 sending: 16
Printer received: 16
Squarer closed squares
Done

总结

  • 关闭channel后,已发送的数据仍然会被接收:在你的例子中,即使naturals被关闭,Squarer协程仍然会接收并处理0到99的所有数据
  • for ... range是处理channel的安全方式:它会自动处理关闭状态,确保所有数据都被处理
  • 这是Go语言并发模型的设计亮点:简洁、安全,避免了常见的并发错误
Go语言圣经》是一本广受好评的教材,旨在帮助读者系统地学习和掌握Go语言。这本书以简明清晰的方式介绍了Go语言的各种特性、语法和用法,是入门和进阶者的理想选择。 首先,该书提供了对Go语言基础知识的全面介绍。它从简单到复杂地解释了Go语言的基本概念,诸如变量、函数、循环和条件语句等等。通过丰富的例子和练习,读者能够逐步理解和掌握这些概念。 其次,该书详细介绍了Go语言的高级特性和用法。读者可以学习到Go语言的面向对象编程、并发编程、网络编程等关键技术。并发编程是Go语言一个独特特性,对于提高程序性能和扩展能力非常重要。 此外,该书还包含了对常见问题和陷阱的讲解,帮助读者避免一些常见的错误和陷阱。同时,书中提供了大量的案例和实践项目,读者可以通过实际操作来巩固所学内容。 《Go语言圣经》以其简洁明了的风格和对细节的深入讲解而闻名。无论是作为初学者的入门指南,还是作为有经验的开发者的参考书,这本书都能满足读者的需求。此外,该书的PDF版本能够方便地在线或离线阅读,为读者提供了更加便捷的学习体验。 综上所述,《Go语言圣经》是一本内容丰富、权威性强的优秀教材。它不仅适合Go语言的初学者,也适用于那些想要深入学习和掌握Go语言开发者。无论是在线阅读还是PDF版本,读者都能够方便地获取和利用这本宝贵的学习资源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值