Why can't a method be defined both for a struc

2020-07-09 10:36发布

Given the setup in the 54th slide of the golang tour:

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)
}

Why can't a method also be defined for the struct as well as the pointer to the struct? That is:

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

Defining this gives the following error:

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

标签: go
2条回答
疯言疯语
2楼-- · 2020-07-09 10:54

While considering for example:

type T U

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

var t T

...we can now invoke M() on t by writing t.M() as the language permits to call a method with a pointer receiver even on its underlying (non pointer) typed instances, i.e. it becomes equivalent to (&t).M().

If it will be permitted to now additionaly define:

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

...then there's no way to tell what is now t.M() supposed to return.

查看更多
Evening l夕情丶
3楼-- · 2020-07-09 11:05

It can. Just define it on the struct and not the pointer. It will resolve both ways

Method Sets

The method set of the corresponding pointer type *T is the set of all methods with receiver *T or T (that is, it also contains the method set of T)

Try live: 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())
}

Update: As per comments I have created an extra example that actually makes use of the Abser interface to illustrate that both the value and the pointer satisfy the interface.

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

查看更多
登录 后发表回答