`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 int
和a := 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 int
和 a := 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<-
c:=make(chan int) 和 c:=make(chan int,1) 有啥区别?