`var a chan int` 和 `a := make(chan int)` 有啥区别?

Posted

技术标签:

【中文标题】`var a chan int` 和 `a := make(chan int)` 有啥区别?【英文标题】:What's the difference between `var a chan int` and `a := make(chan int)`?`var a chan int` 和 `a := make(chan int)` 有什么区别? 【发布时间】:2019-06-22 03:19:44 【问题描述】:

今天我在学习 go 的 channel 和 goroutine。我遇到了一些让我困惑的现象。

我的 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 %d\n", 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)有什么区别,为什么会触发这种恐慌现象?

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

var a = make(chan int) 也一样【参考方案2】:

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 a chan inta := make(chan int) 不是一回事。【参考方案3】:

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

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

这种方式实际上可以为这个 x 在堆中分配一些内存。

顺便说一句,在 golang 中是否模糊地区分了构建在堆栈或堆中的 val。对于map、slice、chan类型等引用类型,在使用前都需要make(),否则会因为nil point错误而panic

【讨论】:

以上是关于`var a chan int` 和 `a := make(chan int)` 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

2022-09-12:以下go语言代码输出什么?A:true;B:false;C:无法编译;D:运行时 panic。 package main func main() { var x chan<-

golang chan 超时

c:=make(chan int) 和 c:=make(chan int,1) 有啥区别?

不能将 chan chan int 类型的变量用作 <-chan <-chan int 值

golang - channel

python 常用方法