Go:* Var是Var的“子类”吗?

时间:2014-10-21 21:52:31

标签: go

取自巡演:

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 = &v

    // v == Vertex != *Vertex -> exception
    a = v
}

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

但是,将func (v *Vertex) Abs() float64转换为func (v Vertex) Abs() float64时,代码会编译:

package main

import (
    "math"
)

type Abser interface {
    Abs() float64
}

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

    a = f

    // Since *Vertex != Vertex, this shouldn't compile, should it?
    a = &v

    a = v
}

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

为什么第二个例子会运行?

1 个答案:

答案 0 :(得分:4)

类型*T不是T的子类,但*T的{​​{3}}将继承T的方法:

  

任何其他类型T的方法集由用接收器类型T声明的所有方法组成。相应指针类型* T的方法集是用receiver * T或T声明的所有方法的集合(也就是说,它也是包含T)的方法集。

因此,如果T符合特定接口,那么*T也是如此。这就是为什么您可以为示例中的*Vertex变量指定Abser值。