微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么传递给通道的值不能被fmt.Println打印出来?

如何解决为什么传递给通道的值不能被fmt.Println打印出来?

func main() {
    links := []string{
        "http://google.com","http://amazon.com","http://golang.org","http://yahoo.com","http://ebay.com",}

    c := make(chan string)

    for _,link := range links {
        testRequest(link,c)
    }
    msg := <-c
    fmt.Println(msg)
}
func testRequest(s string,c chan string) {
    _,err := http.Get(s)
    if err != nil {
        fmt.Println(s,"Is down presently")
        c <- "Something might be down"
        return
    }
    fmt.Println(s,"Is working perfectly")
    c <- "Working great!"
}

通道应该是引用类型,由于某种原因,该函数没有将任何内容传递给通道,因为每次我运行代码时,它都会按预期打印出第一行,但是程序不会停止运行,并且不会执行fmt.Println(channel),所以我的假设是没有任何值传递给频道,这是出于任何原因吗?

解决方法

使用无缓冲通道时,testRequests()中的写入将被阻塞,然后再从main()中的通道进行读取。你陷入僵局。通常,您应该得到一个错误,通常在所有goroutine被阻止时找出错误。不知道为什么你不是。

您可能想在其他goroutine中运行testRequests():

package main

import (
    "fmt"
    "net/http"
)

func main() {
    links := []string{
            "http://google.com","http://amazon.com","http://golang.org","http://yahoo.com","http://ebay.com",}

    c := make(chan string)

    go func() {
            for _,link := range links {
                    testRequest(link,c)
            }
            close(c)
    }()
    for msg := range c {
            fmt.Println(msg)
    }
    fmt.Println("Done handling request")
}

func testRequest(s string,c chan string) {
    _,err := http.Get(s)
    if err != nil {
            fmt.Println(s,"Is down presently")
            c <- "Something might be down"
            return
    }
    fmt.Println(s,"Is working perfectly")
    c <- "Working great!"
}

https://play.golang.org/p/g9X1h_NNJAB

,

您的程序在for第一次循环后被卡住,发送方尝试发送到频道,但接收方只有在循环结束后才能接收

//This loop will blocks until finished
for _,link := range links {
    testRequest(link,c) // Try to send,receiver can't receive
}

//Until above loop finishs,this never excutes
msg := <-c
mt.Println(msg)

使用go运行发送方循环,以便接收方循环可以执行,但是在所有工作完成之前,您需要防止主程序退出。

func main() {
    links := []string{
        "http://google.com",}

    c := make(chan string)

    // This code will not blocks
    go func() {
        for _,link := range links {
            testRequest(link,c)
        }
    }()

    // Above code doesn't block,this code can excutes
    for {
        msg := <-c
        fmt.Println(msg)
    }
}

func testRequest(s string,err := http.Get(s)
    if err != nil {
        fmt.Println(s,"Is down presently")
        c <- "Something might be down"
        return
    }
    fmt.Println(s,"Is working perfectly")
    c <- "Working great!"
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。