我正在對類型參數進行一些實驗,以提出一種通用的方法來連接生成對 JSON HTTP 請求的響應的結構。Method結構必須實現的接口有一個方法SetParams。只要實現使用指針接收器,這就會按預期工作。SetParams我的問題:如果有值接收者,有什么方法可以使它成為編譯時錯誤?SetParams下面是一個示例,它演示了具有值接收者的問題:package mainimport ( "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 }}https://go.dev/play/p/Eii8ADkmDxE
1 回答

心有法竹
TA貢獻1866條經驗 獲得超5個贊
你不能那樣做。
在您的代碼中執行此操作時:
var m T = new(M)
即使T
的類型集僅*M
作為類型術語包含,*M
的方法集也包含聲明在 上的方法M
。編譯器無法為您檢查該方法如何*M
在 的方法集中結束。
SetParam
在聲明該方法時,您有責任BadPing
確保該方法不會嘗試無效地修改接收器。
- 1 回答
- 0 關注
- 159 瀏覽
添加回答
舉報
0/150
提交
取消