为了账号安全,请及时绑定邮箱和手机立即绑定

我可以重新打开已关闭的频道吗?

我可以重新打开已关闭的频道吗?

Go
慕村225694 2023-04-24 16:46:20
我想弄清楚是否可以在关闭频道后重新打开它。测试用例:我有一个频道,里面有一些东西我想覆盖它们,因此我需要事先关闭频道我想在频道中放入更多内容并再次遍历它go func() {    queue <- "1"    queue <- "2"    close(queue)}()for i := range queue {    go func(i string) {        fmt.Println("From queue: ", i)    }(i)}go func() {    open(queue)    queue <- "3"    queue <- "4"    close(queue)}()for i := range queue {    go func(i string) {        fmt.Println("From queue: ", i)    }(i)}当然open不存在。我怎样才能在 Go 中实现我需要的东西?我不想使用睡眠功能
查看完整描述

3 回答

?
紫衣仙女

TA贡献1839条经验 获得超15个赞

我想覆盖它们,因此我需要事先关闭频道


不,不需要关闭频道。当另一个项目通过通道推送时,它将恢复迭代。


下面的代码接受控制台输入并将其推送到频道:


主程序


package main


import (

    "log"

    "bufio"

    "os"

    "fmt"

)


func process(c chan string) {

    for s := range c {

        log.Println("processed", s)

    }

}


func main() {

    c := make(chan string, 10)

    go process(c)


    // get from console and process

    reader := bufio.NewReader(os.Stdin)

    fmt.Println("INPUT STUFF. TYPE #quit TO EXIT.")

    for {

        input, _, _ := reader.ReadLine()

        if string(input) == "#quit" {

            break

        }

        c <- string(input)

    }


    log.Println("BYE!")

}

输出


INPUT STUFF. TYPE #quit TO EXIT.

hello

2018/10/23 10:43:52 processed hello

world

2018/10/23 10:43:54 processed world

#quit

2018/10/23 10:43:57 BYE!

下面的示例使用并可作为 Go Playground片段Sleep()运行


package main


import (

    "log"

    "time"

)


func process(c chan string) {

    for s := range c {

        log.Println("processed", s)

    }

}


func main() {

    c := make(chan string, 10)


    go process(c)


    // push some data

    c <- "barry allen"

    c <- "iris west"


    time.Sleep(time.Second * 2)


    // push more data

    c <- "joe west"

    c <- "caitlin snow"


    time.Sleep(time.Second * 3)

}

输出


2009/11/10 23:00:00 processed barry allen

2009/11/10 23:00:00 processed iris west

2009/11/10 23:00:02 processed joe west

2009/11/10 23:00:02 processed caitlin snow

希望这可以帮助。干杯,


查看完整回答
反对 回复 2023-04-24
?
慕莱坞森

TA贡献1810条经验 获得超4个赞

您不能重新打开已关闭的频道,但可以channel在频道上发送,也许这就是您要找的?

package main


import (

    "fmt"

    "time"

)


func main() {

    queue := make(chan chan int)

    defer close(queue)


    go func() { // reader

        for {

            ch := <-queue

            for i := range ch {

                fmt.Println(i)

            }

            fmt.Println("Done with this channel")

        }

    }()


    go func() { // writer-1

        ch := make(chan int)

        defer close(ch)

        queue <- ch

        ch <- 4

        ch <- 2

    }()


    go func() { // writer-2

        ch := make(chan int)

        defer close(ch)

        queue <- ch

        ch <- 4

        ch <- 20

    }()

    time.Sleep(time.Second)

}


查看完整回答
反对 回复 2023-04-24
?
翻阅古今

TA贡献1780条经验 获得超5个赞

虽然您无法重新打开频道,但可以创建一个新频道并分配给变量。先前关闭的通道将被垃圾收集。在本例中,我重用了该queue变量,但您也可以创建一个新queue2变量并将其传递给 goroutine。


package main


import (

    "context"

    "fmt"

    "time"

)


func main() {

    ctx := context.Background()

    ctx, cancel := context.WithCancel(ctx)

    queue := make(chan int)

    go printFormat(nil, queue)

    queue <- 1

    queue <- 2

    close(queue)

    // fake some actions in between

    time.Sleep(2 * time.Second)

    queue = make(chan int)

    go printFormat(cancel, queue)

    queue <- 3

    queue <- 4

    close(queue)

    <-ctx.Done()

}


func printFormat(c context.CancelFunc, q chan int) {

    for i := range q {

        fmt.Printf("Data %d \n", i)

    }

    if c != nil {

        c()

    }

}


查看完整回答
反对 回复 2023-04-24
  • 3 回答
  • 0 关注
  • 107 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信