【问题标题】:Why can't a method be defined both for a struct and its pointer?为什么不能同时为结构及其指针定义方法?
【发布时间】:2012-11-10 21:07:57
【问题描述】:

鉴于 golang 之旅的54th slide 中的设置:

type Abser interface {
    Abs() float64
}

type Vertex struct {
    X, Y float64
}

func (v *Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

为什么不能同时为结构定义方法以及指向结构的指针?那就是:

func (v Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

定义它会产生以下错误:

prog.go:41: method redeclared: Vertex.Abs
    method(*Vertex) func() float64
    method(Vertex) func() float64

【问题讨论】:

标签: go


【解决方案1】:

可以。只需在结构而不是指针上定义它。它会解决两种方式

Method Sets

对应指针类型*T的方法集合是所有的集合 接收者 *T 或 T 的方法(也就是说,它还包含方法 T 组)

尝试直播:http://play.golang.org/p/PsNUerVyqp

package main

import (
    "fmt"
    "math"
    )

type Abser interface {
    Abs() float64
}

type Vertex struct {
    X, Y float64
}

func (v Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func main() {
    v := Vertex{5, 10}
    v_ptr := &v
    fmt.Println(v.Abs())
    fmt.Println(v_ptr.Abs())
}

更新: 根据 cmets,我创建了一个额外的示例,它实际上使用了 Abser 接口来说明值和指针都满足接口。

https://play.golang.org/p/Mls0d7_l4_t

【讨论】:

  • type Abser interface 未使用。
  • @Tom L 您是说您的 IDE 抱怨您的界面未使用吗?它可能在同一个库中看不到任何实现接口的东西。您的实际观点或问题是什么?
  • 您出色的 Go Playground 示例(可以理解地反映了这个问题)也可以在没有 type Abser interface 的情况下“解决两种方式”。
【解决方案2】:

同时考虑例如:

type T U

func (t *T) M() int { return 1 }

var t T

...我们现在可以通过编写t.M()t 上调用M(),因为语言允许即使在其底层(非指针)类型实例上也可以调用带有指针接收器的方法,即它变得等价于(&t).M().

如果现在允许额外定义:

func (t T) M() int { return 2 }

...那么没有办法知道现在t.M() 应该返回什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-05
    • 1970-01-01
    • 2014-05-30
    • 2021-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多