2013-07-03 122 views

回答

3

The Go Programming Language Specification

Types

A type determines the set of values and operations specific to values of that type.

您希望識別一組特定的值和操作。

例如,

package main 

import "fmt" 

type Coordinate float64 

type Point struct { 
    x, y Coordinate 
} 

func (p *Point) Move(dx, dy Coordinate) { 
    p.x += dx 
    p.y += dy 
} 

func main() { 
    var p = Point{3.14159, 2.718} 
    fmt.Println(p) 
    p.Move(-1, +1) 
    fmt.Println(p) 
} 

輸出:

{3.14159 2.718} 
{2.14159 3.718} 
+2

是的。這不僅有利於使用鍵入,而且有時需要,因爲您不能在基本類型上聲明函數。 – Matt

+1

@Matt:在Go中,它的方法不是函數:「一個類型可能有一個與之相關的方法集。」 [方法集,Go編程語言規範。](http://golang.org/ref/spec#Method_sets) – peterSO

+0

好吧,罰款,語義拋在一邊,我指的是「func」關鍵字。 :P – Matt

5

落後於一般命名類型的原因是相當簡單的,並且是非常大多數語言一樣 - 能夠命名複雜類型,像:

type Person struct{ 
    name String 
    age uint8 
} 

但是,命名一個像你描述的類型,我將其稱爲「鍵入鋸齒「(不知道這是否被其他人使用,但它是我傾向於使用的術語),並不能爲您提供上述優勢。然而,的功能能夠爲現有類型添加方法。 Go不允許你將方法添加到你自己沒有定義的現有類型(即,在其他包中定義的內置類型或類型),所以別名允許你假裝你自己定義了,並因此添加了方法他們。另一種好的思考方式就像創建一個包裝類型的簡潔版本一樣(例如像在Java這樣的OO語言中)。

因此,假設我希望能夠使用整數作爲錯誤。在Go中,error接口只需要一個名爲「Error」的方法,它返回一個字符串。使用類型別名,我可以這樣做:

type errorCode int 

func (e errorCode) Error() string { 
    return fmt.Sprintf("%d", e) 
} 

...我可以使用整數錯誤代碼。相反,如果我嘗試以下,我會得到一個錯誤:

func (e int) Error() string { 
    return fmt.Sprintf("%d", e) 
} 

爲了演示,看看這個實施: http://play.golang.org/p/9NO6Lcdsbq

只是爲了澄清(因爲我使用這個詞的「別名」可誤導),否則兩種類型是等價的(例如,上例中的interrorCode)不可互換。 Go類型系統將它們視爲基本不同的類型,儘管您可以在它們之間進行類型轉換。

+2

這不完全正確。類型別名可用於Scala等語言,並生成具有多個名稱的* single *類型。 Go有一個更好的方法:新類型是獨特的,它們是* not *別名。因此,例如,「類型距離float32」,「類型時間float32」和「類型速度float32」將允許基於明確類型的強類型「func CalcSpeed(d Distance,t Time)Speed」。這使得編譯器可以比如果只有「func CalcSpeed(d float32,t float32)float32」進行更徹底的檢查。 –

+0

對不起,我使用「別名」一詞可能會產生誤導。我的意思是暗示這是一種新型的。我會編輯更正。 – joshlf

+0

_Why_不允許定義現有類型的新方法嗎? – harm