接收方是否确定要采用哪种方法?

时间:2018-07-02 11:36:25

标签: go receiver

围棋之旅:https://tour.golang.org/methods/9

package main

import (
    "fmt"
    "math"
)

type Abser interface {
    Abs() float64
}

func main() {
    var a Abser
    f := MyFloat(-math.Sqrt2)
    v := Vertex{3, 4}

    a = f  // a MyFloat implements Abser
    a = &v // a *Vertex implements Abser

    // In the following line, v is a Vertex (not *Vertex)
    // and does NOT implement Abser.
    a = v

    fmt.Println(a.Abs())
}

type MyFloat float64

func (f MyFloat) Abs() float64 {
    if f < 0 {
        return float64(-f)
    }
    return float64(f)
}

type Vertex struct {
    X, Y float64
}

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

在本练习中,有两种Abs()方法。但是似乎第24行fmt.Println(a.Abs())自动应用了具有与变量相同类型的接收器的接收器。

这是接收器的功能吗?

1 个答案:

答案 0 :(得分:2)

  

The Go Programming Language Specification

     

Method sets

     

类型可能具有与之关联的方法集。一个方法集   接口类型是它的接口。任何其他类型T的方法集   包含所有以接收者类型T声明的方法。方法集   指针类型* T的所有方法的集合   用接收者* T或T声明(也就是说,它还包含方法   T集)。进一步的规则适用于包含嵌入式字段的结构,   如结构类型部分所述。任何其他类型都有   空方法集。在方法集中,每个方法必须具有唯一的   非空白的方法名称。

     

类型的方法集确定该类型的接口   实现以及可以使用该接收器调用的方法   类型。


  

类型的方法集确定该类型的接口   实现以及可以使用该接收器调用的方法   类型。

例如,简化Go Tour示例,

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() {
    var a Abser
    a = &Vertex{3, 4} // a *Vertex implements Abser
    fmt.Println(a.Abs())
}

游乐场:https://play.golang.org/p/cf3WMcBI0WJ

输出:

5

类型a的变量Abser可以包含设置了Abser方法的任何变量类型:Abs() float64。变量a包含一个*Vertex,其满足Abser的方法集func (v *Vertex) Abs() float64。表达式a.Abs()对它当前包含的类型Abs()执行方法*Vertex