Go: *Var 是 Var 的 "subclass"吗?

标签 go

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

但是,当将 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)
}

为什么第二个例子运行?

最佳答案

类型*T 不是T 的子类,而是*Tmethod set将继承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).

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

关于Go: *Var 是 Var 的 "subclass"吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26497002/

相关文章:

python - 如何从 Python 调用 Go 函数

postgresql - COPY 命令运行缓慢

go - 子对象未使用 golang 解析 graphql

MongoDB 查找和迭代 vs 计数

file - "./..."是否表示所有子文件夹?

go - 比较文本文件的列

templates - Golang 文本/模板以及 {{with }} {{end}} 的使用

go - 将 yaml 解析为具有动态字段的结构

mongodb - 使用结构为 Controller 进行模型子类化

go - 理解 Go 中的变量作用域