2014-10-21 34 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變量的原因。