为了账号安全,请及时绑定邮箱和手机立即绑定

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 关注
  • 171 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号