"var a chan int"和"a := make(chan int)"有什么区别?

  • 本文关键字:chan int 区别 var make go
  • 更新时间 :
  • 英文 :


今天我正在学习围棋的频道和套路。我遇到了一些让我感到困惑的现象。

我的 go 文件如下所示:

package main
import (
    "fmt"
)
func testRoutine(number int, channel chan int) {
    channel <- number
}

func main() {
//    var a chan int
    a := make(chan int)
    b := make(chan int)
    go testRoutine(1, a)
    go testRoutine(2, b)
    c, d := <-a, <-b
    fmt.Printf("%d %dn", c, d)
}

当我使用语法a := make(chan int)时,它运行良好。

但是当我把a := make(chan int)改成var a chan int时,我得到了恐慌报告:

fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive (nil chan)]:
main.main()
    /Users/marioluisgarcia/Local/practice/go/cache/var_make_diff.go:19 +0xc7
goroutine 18 [chan send (nil chan)]:
main.testRoutine(0x1, 0x0)
    /Users/marioluisgarcia/Local/practice/go/cache/var_make_diff.go:8 +0x3f
created by main.main
    /Users/marioluisgarcia/Local/practice/go/cache/var_make_diff.go:16 +0x7c
goroutine 19 [chan send]:
main.testRoutine(0x2, 0xc42008a060)
    /Users/marioluisgarcia/Local/practice/go/cache/var_make_diff.go:8 +0x3f
created by main.main
    /Users/marioluisgarcia/Local/practice/go/cache/var_make_diff.go:17 +0xa7

那么,var a chan inta := make(chan int)之间有什么区别,为什么会引发这种恐慌现象呢?

a := make(chan int)创建无缓冲通道。该通道具有零缓冲区。您可以通过它发送数据。

var a chan int创建通道变量并将其设置为默认值 nil并且 nil 通道总是阻塞,这就是您的程序死锁的原因。您不能在 nil 通道中发送数据。

如果打印值,您将看到差异。

package main
import (
    "fmt"
)
func main() {
    var i chan int
    fmt.Println(i)
    a := make(chan int)
    fmt.Println(a)
}

去游乐场链接:https://play.golang.org/p/Bxr6qRfNqZd

回想一下,var name type会创建一个名为 name 的变量,该变量的类型type设置为该类型的默认值。 这意味着var a chan int创建了一个通道,以便a == nil .

然而,var a chan int = make(chan int)a := make(chan int)是相同的。

var x chan int 只是 'x' 的声明,您只在堆栈中创建一个 val,而堆中没有实际的内存 malloc。

var x chan int
x = make(chan int, 0)

这种方式实际上可以在这个 X 的堆中 malloc 一些内存。

顺便说一下,在堆栈或堆中构建的 val 是在 golang 中模糊区分的。对于那些引用类型,如map,slice,chan type,它们都应该在使用之前make(),否则它会因为零点错误而死

最新更新