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

huangapple go评论72阅读模式
英文:

Go: Is *Var a "subclass" of Var?

问题

第一个示例中,func (v *Vertex) Abs() float64 是指针接收器方法,而第二个示例中,func (v Vertex) Abs() float64 是值接收器方法。在Go语言中,接口的方法集由值接收器方法组成。因此,第一个示例中的*Vertex类型实现了Abser接口,而第二个示例中的Vertex类型也实现了Abser接口。这就是为什么第二个示例可以编译通过的原因。

英文:

taken from the go tour:

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

However, when turning func (v *Vertex) Abs() float64 into func (v Vertex) Abs() float64, the code compiles:

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

Why does the second example run?

答案1

得分: 4

类型*T不是T的子类,但是*T方法集将继承T的方法:

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

因此,如果T符合特定的接口,那么*T也会符合。这就是为什么在你的示例中可以将*Vertex的值赋给Abser变量的原因。

英文:

The type *T is not a subclass of T, but *T's method set will inherit the methods of T:

> The method set of any other type T consists of all methods declared with receiver type T. The method set of the corresponding pointer type *T is the set of all methods declared with receiver *T or T (that is, it also contains the method set of T).

So if T conforms to a particular interface, then so will *T. That is why you could assign a *Vertex value to an Abser variable in your example.

huangapple
  • 本文由 发表于 2014年10月22日 05:52:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/26497002.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定