【问题标题】:Why is this statement is unreachable? [closed]为什么这个语句是不可访问的? [关闭]
【发布时间】:2021-03-10 20:50:32
【问题描述】:

此代码是 the-way-to-go 的形式,我对频道的示例感到困惑。为什么for循环后的语句不可达,为什么当ch为空时func getData没有panic完成?

package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan string)

    go sendData(ch)
    go getData(ch)  

    time.Sleep(1e9)
}

func sendData(ch chan string) {
    ch <- "Washington"
    ch <- "Tripoli"
    ch <- "London"
    ch <- "Beijing"
    ch <- "Tokio"
}

func getData(ch chan string) {
    var input string
    // time.Sleep(2e9)
    for {
        input = <-ch
        fmt.Printf("%s ", input)
    }
    fmt.Printf("finished") // unreachable, why???
}

和输出:

./prog.go:32:5: unreachable code
Go vet exited.

Washington Tripoli London Beijing Tokio 
Program exited.

【问题讨论】:

    标签: go channel


    【解决方案1】:

    循环:

    for {
        input = <-ch
        fmt.Printf("%s ", input)
    }
    

    从不退出(它永远循环)所以它后面的任何东西都无法到达。为了使其可访问,需要有一种方法来结束循环,即

    for {
        input = <-ch
        fmt.Printf("%s ", input)
        if input == "fred" {
            break
        }
    }
    fmt.Printf("finished") // no longer unreachable
    

    注意:这可能仍然会永远循环(如果“fred”从未在通道上发送,则它不会退出)。但是,这通常无法在编译时确定。

    一种常用的通道循环方式是使用range;这将在通道关闭时退出:

    for input = range ch {
        fmt.Printf("%s ", input)
    }
    fmt.Printf("finished") // no longer unreachable
    

    为什么当 ch 变空时 func getData 没有恐慌地完成?

    它不会退出;它继续等待另一个值到达通道。但是根据the spec

    程序执行从初始化主包开始,然后调用函数 main。当该函数调用返回时,程序退出。它不会等待其他(非主)goroutine 完成。

    所以当你的time.Sleep(1e9) 完成并且main 退出时,运行getData 的go 例程被终止。

    【讨论】:

      【解决方案2】:
      for {
          input = <-ch
          fmt.Printf("%s ", input)
      }
      fmt.Printf("finished") // unreachable, why???
      

      for循环没有退出条件,内部也没有break,这意味着它永远不会退出这个循环。这就是为什么无法到达循环后面的行的原因。

      【讨论】:

        猜你喜欢
        • 2013-07-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多