Heim >Backend-Entwicklung >Golang >Warum schlagen Schnittstellenaufrufe in meinem Go-Programm fehl?

Warum schlagen Schnittstellenaufrufe in meinem Go-Programm fehl?

WBOY
WBOYOriginal
2023-06-10 09:18:06946Durchsuche

Die Go-Sprache hat sich aufgrund ihrer schnellen und effizienten Eigenschaften zu einer der beliebtesten Programmiersprachen der Welt entwickelt. Die Schnittstelle ist eine leistungsstarke Funktion in der Go-Sprache, die Programmierern eine sehr elegante Möglichkeit bietet, zwischen verschiedenen Strukturen zu interagieren und zu kommunizieren. Wenn Schnittstellenaufrufe jedoch fehlschlagen, ist dies ein häufiges Problem für einige unerfahrene Programmierer. In diesem Artikel werden die Gründe für das Scheitern von Schnittstellenaufrufen untersucht und einige Lösungen bereitgestellt.

  1. Nicht-Zeiger-Schnittstelle

Wenn in der Go-Sprache Daten normalerweise an eine Funktion übergeben werden, werden die Daten in die Parameter der Funktion kopiert. Und wenn wir die Schnittstelle als Parameter an die Funktion übergeben und der Wert des Schnittstellentyps kein Zeigertyp ist, wird er als Werttyp kopiert. Dies kann in einigen Fällen dazu führen, dass Schnittstellenaufrufe fehlschlagen.

Der Schnittstellenaufruf wird durch Aufrufen der Methode des Schnittstellenwerts erreicht. Dies erfordert, dass der Typ des Schnittstellenwerts ein Zeigertyp ist, da die Methode mit dem Zeiger arbeiten muss. Wenn wir einer Schnittstelle einen Wert vom Typ Nicht-Zeiger zuweisen, kopiert die Go-Sprache die internen Daten und erstellt einen neuen Schnittstellenwert. Da dieser neue Schnittstellenwert jedoch kein Zeigertyp mehr ist, können wir Methoden für diesen neuen Schnittstellenwert nicht direkt aufrufen. Aus diesem Grund schlägt der Schnittstellenaufruf fehl.

Wenn wir also Schnittstellen aufrufen und sicherstellen möchten, dass sie ordnungsgemäß funktionieren, müssen wir sicherstellen, dass der Wert des Schnittstellentyps ein Zeigertyp ist.

  1. Nichtübereinstimmung des Schnittstellentyps

Wenn in der Go-Sprache eine Variable kein Schnittstellentyp ist, kann sie keinem Schnittstellentyp zugewiesen werden. Dies liegt daran, dass die Schnittstelle ein dynamischer Typ ist und vom Compiler nicht überprüft werden kann. Wenn die Schnittstellentypen nicht übereinstimmen, schlägt der Schnittstellenaufruf ebenfalls fehl. Schauen Sie sich das folgende Beispiel an:

type Employee struct {
    Name string
    Age  int
}

func (e Employee) ShowName() {
    fmt.Printf("Name is %s
", e.Name)
}

func showName(s interface{}) {
    s.ShowName()
}

func main() {
    emp := Employee{Name: "John", Age: 25}
    showName(emp)
}

Der obige Code generiert den folgenden Fehler:

cannot use emp (type Employee) as type interface {} in argument to showName:
  Employee does not implement interface {} (missing ShowName method)

Der Go-Compiler geht davon aus, dass es sich bei diesem Mitarbeitertyp um einen anderen Typ handelt, sodass er nicht direkt einer Variablen vom Typ interface{} zugewiesen werden kann. Um dieses Problem zu lösen, können wir den Employee-Typ ändern, um die erforderliche Schnittstelle zu implementieren, sodass wir sie als Parameter an die Funktion showName übergeben können.

  1. Unvollständige Schnittstellenimplementierung

Ein weiterer häufiger Fehler bei Schnittstellenaufrufen ist die unvollständige Schnittstellenimplementierung. Kurz gesagt bedeutet dies, dass wir eine Schnittstelle für einen Strukturtyp implementieren, aber nicht alle Methoden der Schnittstelle implementieren. Dies kann zu Fehlern bei Schnittstellenaufrufen führen. Schauen Sie sich das folgende Beispiel an:

type Square struct {
    Side int
}

func (s Square) Area() int {
    return s.Side * s.Side
}

type Shape interface {
    Area() int
}

func PrintArea(s Shape) {
    fmt.Println("Area is", s.Area())
}

func main() {
    sq := Square{Side: 5}
    PrintArea(sq)
}

Der obige Code erzeugt den folgenden Fehler:

cannot use sq (type Square) as type Shape in argument to PrintArea:
        Square does not implement Shape (missing Area method)

In diesem Beispiel haben wir einen Square-Typ und eine Shape-Schnittstelle definiert. Wir haben die Area-Methode für den Square-Typ implementiert. Wir implementieren jedoch keine anderen Methoden der Shape-Schnittstelle. Dies führt dazu, dass Schnittstellenaufrufe in der PrintArea-Funktion fehlschlagen. Stellen Sie daher sicher, dass alle Methoden der Schnittstelle auf dem angegebenen Typ implementiert sind, damit der Schnittstellenaufruf erfolgreich sein kann.

  1. Schnittstellen werden durch Nullwerte überschrieben

In der Go-Sprache können Schnittstellen Nullwerte zugewiesen werden. Das bedeutet, dass wir in einer Schnittstelle den Nullwert als gültigen Wert übergeben können. Dies kann jedoch auch dazu führen, dass der Schnittstellenaufruf fehlschlägt.

Wenn der Schnittstellenwert Null ist, führt der Aufruf von Methoden darauf zu einem Laufzeitfehler. Schauen Sie sich das folgende Beispiel an:

type Calculator interface {
    Add(a int, b int) int
}

func main() {
    var c Calculator
    fmt.Println(c.Add(1, 2))
}

Der obige Code generiert den folgenden Fehler:

panic: runtime error: invalid memory address or nil pointer dereference

Die Lösung besteht darin, dass wir vor der Verwendung einer Schnittstelle mit einem Nullwert sicherstellen müssen, dass der Schnittstellentyp vollständig implementiert wurde, oder Sie können dies tun Verwenden Sie eine Typzusicherung, um festzustellen, ob die Schnittstelle kein Nullwert ist.

func main() {
    var c Calculator
    if c != nil {
        fmt.Println(c.Add(1, 2))
    }
}
  1. Abfolge von Schnittstellenaufrufen

Wenn wir in der Go-Sprache der Schnittstelle einen Nicht-Zeiger-Typwert zuweisen, kopiert Go die internen Daten und erstellt einen neuen Schnittstellenwert. Dieser neue Schnittstellenwert ist auch eine andere Schnittstelle mit demselben Wert. Wenn wir daher eine Methode in einer Schnittstelle aufrufen, müssen wir den Methodenaufruf außerhalb der Schnittstelle mit einem primitiven Typwert oder einem Zeigertyp auf einen primitiven Wert durchführen.

Sehen Sie sich das folgende Beispiel an:

type Employee struct {
    Name string
    Age  int
}

func (e Employee) ShowName() {
    fmt.Printf("Name is %s
", e.Name)
}

type NameShower interface {
    ShowName()
}

func main() {
    emp := Employee{Name: "John", Age: 25}
    var ns NameShower
    ns = emp
    ns.ShowName()

    pemp := &Employee{Name: "Doe", Age: 30}
    ns = pemp
    ns.ShowName()
}

Im obigen Code definieren wir einen Employee-Typ und eine NameShower-Schnittstelle. Wenn wir emp erstellen und es ns zuweisen, schlägt der Schnittstellenaufruf fehl, da emp kein Zeigertyp auf einen primitiven Wert ist. Wir müssen einen Zeiger auf emp verwenden, um die ShowName-Methode aufzurufen.

Wenn pemp erstellt und ns zugewiesen wird, ist der Schnittstellenaufruf erfolgreich, da pemp ein Zeigertyp auf einen primitiven Wert ist. Stellen Sie daher sicher, dass wir den richtigen Typ verwendet haben, bevor Sie einen Schnittstellenaufruf durchführen.

Fazit

Durch diesen Artikel kennen wir bereits die Gründe, warum Schnittstellenaufrufe in Go-Programmen fehlschlagen. Fassen wir als Nächstes zusammen:

  • Stellen Sie sicher, dass Sie den Schnittstellen Zeigertypwerte zuweisen.
  • Stellen Sie sicher, dass alle Methoden der Schnittstelle auf dem angegebenen Typ implementiert sind.
  • Stellen Sie sicher, dass der Wert vor dem Aufruf der Schnittstelle nicht Null ist, oder verwenden Sie eine Typzusicherung, um festzustellen, dass die Schnittstelle kein Nullwert ist.
  • Wenn wir für Methodenaufrufe in der Schnittstelle Nicht-Zeiger-Typwerte verwenden, stellen Sie sicher, dass Sie den richtigen Typ verwenden.

Wenn Sie der oben genannten Methode folgen, wird der Schnittstellenaufruf in Ihrem Go-Programm nicht fehlschlagen.

Das obige ist der detaillierte Inhalt vonWarum schlagen Schnittstellenaufrufe in meinem Go-Programm fehl?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn