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

Today I'm learning channels and goroutine of go. And I met some phenomenon which confuses me.

My go file looks like this:

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
", c, d)
}

it works well when I used syntax a := make(chan int).

But when I changed a := make(chan int) to var a chan int, I got panic report:

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

So, is there any difference between var a chan int and a := make(chan int), and why this panic phenomenon was triggered?

Recall that var name type creates a variable named name of type type set to the default value for that type. This means that var a chan int creates a channel such that a == nil.

var a chan int = make(chan int) and a := make(chan int) are, however, the same.

a := make(chan int) creates unbuffered channel. That channel with zero buffer. You can send data through it.

var a chan int creates channel variable and sets it to default value which is nil. And a nil channel is always blocking, that's why your program is deadlocked. You can not send data in nil channel.

If you print the values, you will see the difference.

package main

import (
    "fmt"
)

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

Go playground link: https://play.golang.org/p/Bxr6qRfNqZd

var x chan int is only a declare for 'x' , you only create a val in the stack without actual memory malloc in the heap.however,

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

this way can actually malloc some memory in the heap for this x.

By the way, whether a val built in the stack or the heap is telled apart fuzzily in golang. For those reference types like map,slice,chan type, they all should make() before put to used, or it will panic as nil point error