editor php Baicao memperkenalkan kepada anda peraturan antara muka wajib dalam bahasa Go, iaitu, hanya jenis dengan penerima penunjuk pada kaedah boleh memenuhi keperluan antara muka. Bahasa Go ialah bahasa pengaturcaraan bertaip statik yang melaksanakan polimorfisme melalui antara muka. Apabila mentakrifkan antara muka, anda boleh menentukan jenis penerima kaedah, yang boleh menjadi jenis nilai atau jenis penunjuk. Walau bagaimanapun, apabila kami menggunakan peraturan antara muka wajib, hanya jenis dengan penerima penunjuk pada kaedah boleh memenuhi keperluan antara muka Ini kerana jenis penunjuk boleh mengubah suai kandungan nilai, tetapi jenis nilai tidak boleh. Peraturan ini memastikan kaedah antara muka tidak menyebabkan tingkah laku yang tidak dapat diramalkan apabila memanipulasi nilai. Dengan memahami peraturan ini, kami boleh lebih memahami penggunaan dan reka bentuk antara muka dalam bahasa Go.
Saya sedang melakukan beberapa eksperimen dengan parameter jenis untuk menghasilkan cara umum menggabungkan struktur untuk menjana respons kepada permintaan http json.
Kaedah yangmethod
接口有一个setparams
struktur mesti laksanakan. Selagi pelaksanaan menggunakan penerima penunjuk, ini akan berfungsi seperti yang diharapkan.
Soalan saya: Jikasetparams
mempunyai penerima nilai, adakah ada cara untuk menjadikannya ralat masa kompilasi?
Contoh berikut menunjukkan masalahsetparams
dengan penerima nilai:
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
Anda tidak boleh melakukan ini.
Apabila anda melakukan perkara berikut dalam kod anda:
var m T = new(M)
Malaht
的类型集仅包括*m
作为类型项,*m
的方法集也包括在m
上声明的方法。编译器无法检查该方法如何出现在*m
kaedahnya fokus.
Padabadping
上声明方法setparam
adalah menjadi tanggungjawab anda untuk memastikan kaedah tersebut tidak sia-sia untuk mengubah suai penerima.
Atas ialah kandungan terperinci Go - Paksa antara muka untuk berpuas hati hanya dengan jenis dengan penerima penunjuk pada kaedah?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!