Heim  >  Artikel  >  Backend-Entwicklung  >  Was ist der Grund für Gos „Type Assertion“-Ansatz?

Was ist der Grund für Gos „Type Assertion“-Ansatz?

王林
王林nach vorne
2024-02-06 08:12:07891Durchsuche

Go 的“类型断言”方式背后的原因是什么?

Frageninhalt

Ich versuche zu verstehen, dass Golangs Typzusicherungen nur für Variablen gelten, die explizit als Schnittstellentypen definiert sind, nicht für konkrete Typen (d. h. „string“, „int32“) usw. ).

Hier ist ein schnelles und einfaches Codebeispiel, das die Grundursache meiner Verwirrung veranschaulicht:

package main

import "fmt"

// here we define an interface type:
type Shape interface {
    DoubleSize() int32
}

// here we define a new type which is really just an int32:
type Rect int32

// here we make "Rect" type above comply with the "Shape" interface by implementing the methods of that interface
// and so, since the interfaces in Go are implemented implicitly, this should make the "Rect" type an implicit instance of the "Shape" interface
func (theShape Rect) DoubleSize() int32 {
    return int32(theShape) * 2
}

// this function expects its "someShape" parameter to be of "Shape" type (or "the type that quacks like "Shape" interface does))
func whateverFunction(someShape Shape) int32 {
    return someShape.DoubleSize()
}

func main() {
    var newRect = Rect(5)
    // ^^ if this is instead written as "var newRect Shape = Rect(5)" no error with type assertion happens down the line

    whateverFunction(newRect) // the function works just fine because "newRect" implicitly implements the "Shape" interface — the one that this function expects to receive.  

    // !! but type assertion doesn't work on "newRect"
    v, ok := newRect.(Shape) // error: invalid operation: newRect (variable of type Rect) is not an interface
    if !ok {
        fmt.Println("type assertion failed")
        return
    }
    fmt.Println("This is v:", v)
}
Wie der Titel dieser Frage vermuten lässt, kann ich die Gründe für die Implementierung von Typzusicherungen nur für Schnittstellentypen und die Prüfung, ob der zugrunde liegende Wert, der einer Variablen zugewiesen ist, die diese Schnittstelle explizit implementiert, der von uns intern angegebene Wert ist, nicht verstehen.(t)“ Behauptungsmethode. Dies lässt mich denken, dass „Typzusicherung“ eine unbeabsichtigte Fehlbezeichnung ist, was bedeutet, dass sie für alle Typen gilt, aber nicht nur für Schnittstellentypen.

Ich meine, es muss offensichtlich einen Grund für diese Sprachdesign-Entscheidung geben, und ich denke, es könnte etwas mit der idiomatischen Art und Weise zu tun haben, wie Golang geschrieben wird, aber obwohl ich zu diesem Thema Unmengen von Ressourcen gesehen habe, gibt es das nie Geben Sie an, warum.

Der Grund, warum es für mich Sinn macht, ist, dass ein Go-Programm „besser (ich nehme an, da die explizite Schnittstellendefinition optional ist)“ mit allen Variablen geschrieben werden sollte, die eine bestimmte Schnittstelle (Verhalten) darstellen. Aus Gründen der Klarheit und Lesbarkeit sollte daher ein explizites definiert werden Schnittstellen zu Variablen sind sinnvoll.

Aber wie ich bereits erwähnt habe, habe ich noch nie eine Ressource gesehen, die speziell erklärt, warum die Funktion „Typzusicherung“ in go implementiert ist, und ich hoffe, Sie können mir helfen, diese Verwirrung zu beseitigen.

-- Aktualisierung 1 - Zur Klärung meiner Frage wurden einige Inhalte hinzugefügt:

Ich denke, meine Kernfrage betrifft den Grund (den ich nicht verstehe), dass die Typzusicherung nur funktioniert, wenn die Schnittstelle der Variablen explizit implementiert wird, und nicht, wenn die Schnittstelle implizit implementiert wird.

Wie durch „whateverfunction“ demonstriert, betrachtet der Code „newrect“ als Implementierung der „Shape“-Schnittstelle oder als „eine Implementierung der „Shape“-Schnittstelle“ (ansonsten wäre die Funktion nicht auf die Variable anwendbar, aber das tut es), aber der Code hinter der Typzusicherungsmethode „.(t)“ behandelt „newrect“ nicht als Implementierung der „Shape“-Schnittstelle.

Wenn es also Unterschiede in den Überlegungen zur Schnittstellenimplementierung in Golang gibt, muss es meiner Meinung nach einen Grund (Differenzierung) für solche Designentscheidungen geben.

Deshalb habe ich erwähnt, dass der einzige Grund, der mir bisher einfällt, darin besteht, ob dies eine Möglichkeit ist, Leute dazu zu bringen, auf irgendeine Weise Go-Code zu schreiben.


Richtige Antwort


Sie können sich die Antwort von Burak Serdar ansehen – vielleicht finden Sie sie prägnanter und hilfreicher. Dennoch werde ich die gesamte Argumentationskette posten, die bei mir letztendlich „Klick“ gemacht hat:

|-> Schnittstellen werden verwendet, wenn wir nicht sicher sind, welche Art von Daten wir genau erwarten (da beispielsweise derselbe Parameter in einer Funktion in einem Programm aufgrund von Benutzereingaben unterschiedliche Datentypen empfangen kann). ), aber wir kennen das genaue Verhalten, das die bereitgestellten Daten haben sollten.

^^ Daher ist der tatsächliche Typ des in der Schnittstelle gespeicherten Werts zur Kompilierungszeit nicht bekannt. (Andernfalls würden wir es natürlich im Code angeben.)

|. -> Somit erhalten wir Typzusicherungen, um das Verhalten des Programms in Bezug auf die möglichen Werte definieren zu können, die wir während der Ausführung erwarten.

|-> Daher gelten Typzusicherungen nur für Variablen, die explizit als Schnittstellentyp angegeben sind, nicht für Variablen, die möglicherweise dieselbe Schnittstelle implementieren, aber nicht explizit als Schnittstellentyp angegeben sind

weil

Wenn wir Schnittstellen verwenden, benötigen wir diese Typzusicherung nur zur Laufzeit, da wir den genauen Datentyp, der an das Programm gesendet wird, nicht kennen. Diese Typzusicherung wird nur bei der Verwendung von Schnittstellen benötigt, daher gelten Typzusicherungen nur für den Typ A das explizit als Schnittstellentyp angegeben wird, weil in allen anderen Fällen der Datentyp bekannt ist (wodurch der Compiler implizit davon ausgehen kann, dass die Variable die Schnittstelle implementiert – da er bereits alle Datentypen der beteiligten Daten kennt), ist dies bei uns einfach nicht der Fall Typzusicherungen sind für Daten bekannter Typen erforderlich.

Das obige ist der detaillierte Inhalt vonWas ist der Grund für Gos „Type Assertion“-Ansatz?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen