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

时间:2019-01-29 03:50:15

标签: go

今天,我正在学习go的频道和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)之间有什么区别,为什么会引发这种恐慌现象?

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

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

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

答案 2 :(得分:1)

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

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

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

顺便说一句,无论是在堆栈中建立的val还是在golang中模糊地区分了val。对于诸如map,slice,chan type之类的引用类型,它们都应在使用前make(),否则将由于零点错误而惊慌