goroutine 语句执行和函数执行的不同行为

goroutine different behaviour for statement execution and function execution

谁能解释一下关于 goroutines 的以下两个调用之间的区别?

方法一

fmt.Println("Starting srv")
go LOGGER.Error(srv.ListenAndServe())
fmt.Println("Starting intSrv")
go LOGGER.Error(intSrv.ListenAndServe())

执行 "Starting srv"

后停止

方法二

go func() {
    fmt.Println("Starting srv")
    srv.ListenAndServe()
}()

go func() {
    fmt.Println("Starting intSrv")
    intSrv.ListenAndServe()
}()

这会同时执行 "Starting srv" 和 "Starting intSrv"

为什么行为不同?

协程函数参数在调用协程中计算。

在下面的语句中:

go LOGGER.Error(srv.ListenAndServe())

表达式 srv.ListenAndServe() 在启动 goroutine 之前计算错误以记录错误。对 srv.ListenAndServe() 的调用不会 return 直到服务器退出(因为服务器已停止或侦听器遇到错误)。

使用此代码启动服务器并记录来自服务器的错误 return。

go func() { LOGGER.Error(srv.ListenAndServe()) }()
go LOGGER.Error(srv.ListenAndServe())

上面的语句首先对 LOGGER.Error() 的参数求值,然后创建一个 goroutine 并运行 LOGGER.Error()。但是,srv.ListenAndServe 从来没有 returns.