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