Aujourd'hui, j'apprends les chaînes et la goroutine de go. Et j'ai rencontré un phénomène qui me trouble.
Mon fichier go ressemble à ceci:
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
cela fonctionne bien quand j'ai utilisé la syntaxe a: = make (chan int) .
Mais quand j'ai changé a: = make (chan int) en var a chan int , j'ai reçu un rapport de panique :
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)
}
Alors, y a-t-il une différence entre var a chan int et a: = make (chan int) , et pourquoi ce phénomène de panique s'est-il déclenché?
3 Réponses :
Rappelez-vous que var name type crée une variable nommée name de type type définie sur la valeur default pour ce type. Cela signifie que var a chan int crée un canal tel que a == nil .
var a chan int = make (chan int) et a: = make (chan int) sont, cependant, les mêmes.
var a = make (chan int) serait également le même
a: = make (chan int) crée un canal sans tampon. Ce canal avec zéro tampon. Vous pouvez y envoyer des données.
var a chan int crée une variable de canal et la définit sur la valeur par défaut qui est nil . Et une chaîne nil est toujours bloquante, c'est pourquoi votre programme est bloqué. Vous ne pouvez pas envoyer de données dans le canal nil .
Si vous imprimez les valeurs, vous verrez la différence.
package main
import (
"fmt"
)
func main() {
var i chan int
fmt.Println(i)
a := make(chan int)
fmt.Println(a)
}
Aller au lien du terrain de jeu: https://play.golang.org/p/Bxr6qRfNqZd p >
Une réponse simplement approfondie, canal sans tampon et nul. var a chan int et a: = make (chan int) ne sont pas exactement la même chose.
var x chan int n'est qu'une déclaration pour 'x', vous créez uniquement un val dans la pile sans mémoire réelle malloc dans le tas. Cependant,
var x chan int x = make(chan int, 0)
de cette façon peut en fait ajouter de la mémoire dans le tas pour ce x.
Au fait, si un val construit dans la pile ou le tas est brouillé en golang. Pour les types de référence comme map, slice, chan type, ils devraient tous make () avant d'être utilisés, ou cela paniquera comme une erreur de point nul