2014-10-21 62 views
0

从去游览采取:转:Is * Var是Var的“子类”吗?

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

为什么在第二个例子中运行?

回答

4

类型*T不是T一个亚类中,但*Tmethod set将继承的T方法:

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

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