亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Go - 強制接口僅由方法上具有指針接收器的類型滿足?

Go - 強制接口僅由方法上具有指針接收器的類型滿足?

Go
臨摹微笑 2023-03-15 15:21:30
我正在對類型參數進行一些實驗,以提出一種通用的方法來連接生成對 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確保該方法不會嘗試無效地修改接收器。


查看完整回答
反對 回復 2023-03-15
  • 1 回答
  • 0 關注
  • 159 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號