web-dev-qa-db-fra.com

Pourquoi Go a-t-il tapé nil?

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é?

22
Eonil

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.

14
Sean

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.

Exemple de terrain de jeu

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 .

12
Intermernet

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.

  • Pointeurs
  • Pointeurs dangereux
  • Des interfaces
  • Canaux
  • Plans
  • Les tranches
  • Les fonctions

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.

1
Konrad Borowski