Heim >Backend-Entwicklung >Golang >Go generics: ungültiges zusammengesetztes Literal

Go generics: ungültiges zusammengesetztes Literal

王林
王林nach vorne
2024-02-08 22:00:111255Durchsuche

Go 泛型:无效的复合文字

php-Editor Xigua bringt Ihnen die neuesten Informationen – „Go Generics: Ungültiges zusammengesetztes Literal“. In der Go-Sprachgemeinschaft waren Generika schon immer ein Thema großer Besorgnis. Mit der Veröffentlichung von Go 1.18 werden Generika offiziell in die Standardbibliothek der Go-Sprache aufgenommen. Allerdings ist diese Entscheidung nicht für alle akzeptabel. In diesem Artikel werden die Implementierung von Generika in der Go-Sprache und die damit verbundenen Kontroversen und Diskussionen erörtert, um den Lesern ein besseres Verständnis dieser Technologie zu ermöglichen und eine Referenz für ihre Anwendung in der tatsächlichen Entwicklung bereitzustellen.

Frageninhalt

Der folgende Code verursacht den Fehler „Ungültiger zusammengesetzter Literaltyp t“.

package main

import "fmt"

func main() {
    fmt.Println(createThing[foo]())
}

type thing interface {
    foo | bar
}

type foo struct {
    id int
    a  string
}

type bar struct {
    id int
    b  int
}

func createThing[T thing, P *T]() P {
    return &T{}
}

Wenn ich einfach die Schnittstelle thing中包含thing,或者删除a stringb int,那么foobargenau gleich mache, läuft der Code ohne Fehler. Wird dadurch jedoch der Zweck von Generika zunichte gemacht? Warum kann ich einen solchen generischen Typ nicht instanziieren, insbesondere wenn ich nicht einmal Zugriff auf irgendwelche Felder habe?

Möglicherweise im Zusammenhang mit https://github.com/golang/go/issues/48522

Problemumgehung

Die meisten generischen Typen sind keine gültigen Typen für zusammengesetzte Literale. Dies ist jedoch kein Problem, da es andere Möglichkeiten gibt, Werte generischer Typen zu erstellen.

Erstellen Sie einen Zeiger auf den neuen Nullwert:

func creatething[t thing]() *t {
    return new(t)
}

Oder erstellen Sie einen Nicht-Zeiger-Nullwert:

func createThing[T thing]() T {
    var value T
    return value
}

Was warum der Fehler auf diese Weise betrifft, finden Sie hier die Erklärung aus der Spezifikation, die zur Lösung Ihres spezifischen Problems geändert wurde.

Für zusammengesetzten Text:

Der Kerntyp t von literaltype muss ein Struktur-, Array-, Slice- oder Map-Typ sein

Was ist der Kerntyp?

Schnittstelle t hat Kerntypen, wenn [...] ein einzelner Typ u existiert, der der zugrunde liegende Typ für alle Typen im Typsatz von t ist

Keine andere Schnittstelle verfügt über Kerntypen.

Was ist der zugrunde liegende Typ?

Jeder Typ t hat einen zugrunde liegenden Typ: Wenn t einer der vordeklarierten booleschen, numerischen oder String-Typen oder ein Typliteral ist, ist der entsprechende zugrunde liegende Typ t selbst. Andernfalls ist der zugrunde liegende Typ von t der zugrunde liegende Typ des Typs, auf den t in seiner Deklaration verweist.

„Typliterale“ können sich auf literale Strukturtypen beziehen, z. B. struct{int id}。因此,当 foobar 都具有 struct{int id}底层类型时,则 thing 具有 struct{int id}核心类型,因此复合文字是可能的。当 foobar 没有相同的底层类型时,则 thing Es gibt keine Kerntypen und zusammengesetzte Literale sind nicht möglich, daher Ihr Fehler.

Die formale Definition mag komplex erscheinen, aber das Ergebnis und die praktische Bedeutung sind einfach: Generischer Code kann nur gemeinsames Verhalten möglicher Typen ausdrücken. Literale Werte sind kein übliches Verhalten, außer in dem Sonderfall, in dem alle zugrunde liegenden Typen gleich sind.

Das obige ist der detaillierte Inhalt vonGo generics: ungültiges zusammengesetztes Literal. 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