Pourquoi Go a-t-il typénil
? Il lance une vérification de conformation d'interface explicite pour plus de commodité. Quel est le problème de nil
non typé et qu'est-ce que les concepteurs ont voulu résoudre avec nil
typé?
On dirait que vous vous interrogez sur ce message d'erreur:
http://play.golang.org/p/h80rmDYCTI
package main
import "fmt"
type A struct {}
type B struct {}
func (a *A) Foo() {
fmt.Println("A")
}
func (b *B) Foo() {
fmt.Println("B")
}
func main() {
n := nil
n.Foo()
}
Cela imprime:
prog.go:17: use of untyped nil
[process exited with non-zero status]
Dans cet exemple, le programme doit-il imprimer "A" ou "B"?
Vous devez aider le compilateur à décider. Pour ce faire, vous devez spécifier le type de n
.
Par exemple:
http://play.golang.org/p/zMxUFYgxpy
func main() {
var n *A
n.Foo()
}
imprime "A".
Dans d'autres langues, n.Foo()
peut se bloquer immédiatement si n
est nil
ou son équivalent. Les concepteurs linguistiques de Go ont décidé de vous laisser déterminer ce qui devrait se passer à la place. Si vous accédez au pointeur sans rechercher nil
, vous obtenez le même comportement que dans les autres langues.
Cela est dû à la sécurité de type. nil
est en fait la valeur de uninitialized variables dans Go. Les valeurs nil
pour les tranches, les cartes, les fonctions, les canaux, les pointeurs et les interfaces ne sont pas du même type et ne sont pas comparables. Voir La langue spécifiée pour plus de détails.
EDIT: Comme indiqué par @newacct , le terme technique correct pour cela est la "valeur zéro" pour le type:
Lorsque la mémoire est allouée pour stocker une valeur, via une déclaration ou un appel de marque ou nouvelle, et qu'aucune initialisation explicite n'est fournie, une initialisation par défaut est attribuée à la mémoire. Chaque élément d'une telle valeur est défini sur la valeur zéro pour son type: false pour les booléens, 0 pour les entiers, 0.0 pour les flottants, "" pour les chaînes et nil pour les pointeurs, fonctions, interfaces, tranches, canaux et mappes.
Il existe également des informations concernant les interfaces nil et les erreurs à l'adresse Pourquoi ma valeur d'erreur nil n'est-elle pas égale à nil? dans le Go FAQ .
Toutes les variables de Golang doivent avoir un type. L'utilisation de :=
induit le type à partir du type d'expression de droite.
x := [0]int{} // var x [0]int
y := make(chan int) // var y chan int
z := map[int]int{} // var z map[int]int
a := func(int) {} // var a func(int)
b := 42 // var b int
c := 42.0 // var c float64
Pour presque toutes les expressions, son type est sans ambiguïté, car il est nécessaire de spécifier explicitement le type quelque part - ou, dans le cas de littéraux numériques, avec une valeur par défaut lorsqu'elle n'est pas spécifiée. La seule exception à cette règle est nil
.
n := nil // var n ???
nil
est une valeur valide pour ce qui suit.
Il n'y a pas de bonne valeur par défaut pour un type lorsqu'un utilisateur tape nil
, donc Golang la rejette, nécessitant une spécification de type explicite.