php-Editor Baicao stellt Ihnen die obligatorischen Schnittstellenregeln in der Go-Sprache vor, das heißt, nur Typen mit Zeigerempfängern auf Methoden können die Anforderungen der Schnittstelle erfüllen. Die Go-Sprache ist eine statisch typisierte Programmiersprache, die Polymorphismus über Schnittstellen implementiert. Beim Definieren einer Schnittstelle können Sie den Empfängertyp der Methode angeben, der ein Werttyp oder ein Zeigertyp sein kann. Wenn wir jedoch verbindliche Schnittstellenregeln verwenden, können nur Typen mit Zeigerempfängern auf Methoden die Anforderungen der Schnittstelle erfüllen. Dies liegt daran, dass Zeigertypen den Inhalt des Werts ändern können, Werttypen jedoch nicht. Diese Regel stellt sicher, dass Schnittstellenmethoden bei der Manipulation von Werten kein unvorhersehbares Verhalten verursachen. Wenn wir diese Regel verstehen, können wir die Verwendung und das Design von Schnittstellen in der Go-Sprache besser verstehen.
Ich experimentiere gerade mit Typparametern, um eine allgemeine Methode zum Verketten von Strukturen zu finden, um Antworten auf JSON-HTTP-Anfragen zu generieren.
Methoden, die die method
接口有一个 setparams
Struktur implementieren muss. Solange die Implementierung Zeigerempfänger verwendet, funktioniert dies wie erwartet.
Meine Frage: Wenn setparams
einen Wertempfänger hat, gibt es eine Möglichkeit, daraus einen Fehler bei der Kompilierung zu machen?
Das folgende Beispiel verdeutlicht das Problem von setparams
mit einem Wertempfänger:
package main import ( "encoding/json" "fmt" "log" ) type PingParams struct { Name string } type PingResponse struct { Message string } func (p PingParams) Greeting() string { if p.Name != "" { return fmt.Sprintf("Hello, %s", p.Name) } return fmt.Sprintf("Hello, nobody!") } type GoodPing struct { Params PingParams } // SetParams has a pointer receiver. func (m *GoodPing) SetParams(p PingParams) { fmt.Printf("assign %v with pointer receiver, Good!\n", p) m.Params = p } func (m GoodPing) Run() (*PingResponse, error) { return &PingResponse{Message: fmt.Sprintf("%T %s", m, m.Params.Greeting())}, nil } type BadPing struct { Params PingParams } // SetParams has a value receiver. func (m BadPing) SetParams(p PingParams) { fmt.Printf("assign %v with value receiver, Bad!\n", p) m.Params = p } func (m BadPing) Run() (*PingResponse, error) { return &PingResponse{Message: fmt.Sprintf("%T %s", m, m.Params.Greeting())}, nil } type Method[M, RQ, RS any] interface { // Run builds the RPC result. Run() (*RS, error) // SetParams is intended to set the request parameters in the struct implementing the RPC method. // This then allows the request parameters to be easily available to all methods of the Method struct. // The method MUST have a pointer receiver. This is NOT enforced at compile time. SetParams(p RQ) // The following line requires the implementing type is a pointer to M. *M // https://stackoverflow.com/a/72090807 } func HandlerMethod[M, RQ, RS any, T Method[M, RQ, RS]](in json.RawMessage) (*RS, error) { // A real implementation of this would return a func for wiring into a request router var req RQ err := json.Unmarshal(in, &req) if err != nil { return nil, err } var m T = new(M) m.SetParams(req) return m.Run() } func main() { payload := []byte(`{"Name": "Mark"}`) bad, err := HandlerMethod[BadPing, PingParams, PingResponse](payload) if err != nil { log.Fatal(err) } fmt.Println(bad.Message) good, err := HandlerMethod[GoodPing, PingParams, PingResponse](payload) if err != nil { log.Fatal(err) } fmt.Println(good.Message) }
https://go.dev/play/p/eii8adkmdxe
Das ist nicht möglich.
Wenn Sie in Ihrem Code Folgendes tun:
var m T = new(M)
Sogart
的类型集仅包括*m
作为类型项,*m
的方法集也包括在m
上声明的方法。编译器无法检查该方法如何出现在 *m
die Methode ist fokussiert.
Bei badping
上声明方法 setparam
liegt es in Ihrer Verantwortung sicherzustellen, dass die Methode nicht vergeblich versucht, den Empfänger zu verändern.
Das obige ist der detaillierte Inhalt vonGo - Erzwingen, dass die Schnittstelle nur von Typen mit Zeigerempfängern auf Methoden erfüllt wird?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!