Null-Nil-Schnittstellenvergleichsrätsel
Obwohl die Fehlerschnittstelle erfüllt ist, verhält sich eine Struktur mit einer nil-Instanz nicht wie erwartet im Vergleich zu Null.
Frage:
Warum gibt der folgende Code nicht „Fehler ist Null“ aus?
<code class="go">type Goof struct {} func (goof *Goof) Error() string { return fmt.Sprintf("I'm a goof") } func TestError(err error) { if err == nil { fmt.Println("Error is nil") } else { fmt.Println("Error is not nil") } } func main() { var g *Goof // nil TestError(g) // expect "Error is not nil" }</code>
Antwort:
In Go berücksichtigen Schnittstellenvergleiche sowohl Typ als auch Wert. Während der Typ Goof die Schnittstelle error implementiert, hat eine nil-Instanz von Goof (*Goof)(nil) einen anderen Typ als Fehler (nil).
Lösung:
Um dieses Problem zu beheben, können Sie einen der folgenden Ansätze anwenden:
Weitere Einzelheiten finden Sie in der erweiterten Antwort unten:
Erweiterte Antwort:
Schnittstellenwerte bestehen aus zwei Komponenten: einem Typ und einem dynamischer Wert. Ein nil-Schnittstellenwert enthält sowohl einen nil-Typ als auch einen nil-Wert. In unserem Fall hat (*Goof)(nil) einen Nicht-Null-Typ (Goof), aber einen Null-Wert.
Darüber hinaus prüft der Gleichheitsoperator (==) von Go streng die Typidentität. Daher schlägt der Vergleich von (*Goof)(nil) mit error(nil) fehl, da es sich um unterschiedliche Typen handelt.
Dieses Verhalten stimmt mit anderen Typprüfungen in Go überein. Im folgenden Code sind beispielsweise die zugrunde liegenden Daten dieselben (3), aber die Variablen haben unterschiedliche Typen, was bei der Speicherung in Schnittstellen zu Ungleichheiten führt:
<code class="go">var x int = 3 var y Bob = 3 var ix, iy interface{} = x, y fmt.Println(ix == iy) // false</code>
Das obige ist der detaillierte Inhalt vonWarum ist eine Nullinstanz einer Struktur, die die Fehlerschnittstelle erfüllt, nicht gleich Null?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!