我正在对类型参数进行一些实验,以提出一种通用的方法来连接生成对 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 关注
- 171 浏览
添加回答
举报
0/150
提交
取消