站長資訊網
        最全最豐富的資訊網站

        Go語言類型別名是什么

        在Go語言中,類型別名就是為已存在的“類型”定義一個別名,可以使用type關鍵字來定義,語法“type TypeAlias = Type”。類型別名是Go 1.9版本添加的新功能,主要用于解決代碼升級、遷移中存在的類型兼容性問題;在 C/C++ 語言中,代碼重構升級可以使用宏快速定義一段新的代碼,Go語言中沒有選擇加入宏,而是解決了重構中最麻煩的類型名變更問題。

        Go語言類型別名是什么

        本教程操作環境:windows7系統、GO 1.18版本、Dell G3電腦。

        Go語言 類型別名是什么

        Golang 中類型別名就是為已存在的 類型 定義一個別名。Golang 中類型別名使用 type 關鍵字來定義。

        語法

        type TypeAlias = Type
        登錄后復制

        登錄后復制

        參數

        參數 描述
        type 定義類型別名使用的關鍵字。
        TypeAlias Type 的別名。
        Type 需要起別名的類型。

        類型別名是 Go 1.9 版本添加的新功能,主要用于解決代碼升級、遷移中存在的類型兼容性問題。在 C/C++ 語言中,代碼重構升級可以使用宏快速定義一段新的代碼,Go語言中沒有選擇加入宏,而是解決了重構中最麻煩的類型名變更問題。

        在 Go 1.9 版本之前定義內建類型的代碼是這樣寫的:

        type byte uint8 type rune int32
        登錄后復制

        而在 Go 1.9 版本之后變為:

        type byte = uint8 type rune = int32
        登錄后復制

        這個修改就是配合類型別名而進行的修改。

        區分類型別名與類型定義

        定義類型別名的寫法為:

        type TypeAlias = Type
        登錄后復制

        登錄后復制

        類型別名規定:TypeAlias 只是 Type 的別名,本質上 TypeAlias 與 Type 是同一個類型,就像一個孩子小時候有小名、乳名,上學后用學名,英語老師又會給他起英文名,但這些名字都指的是他本人。

        類型別名與類型定義表面上看只有一個等號的差異,那么它們之間實際的區別有哪些呢?下面通過一段代碼來理解。

        package main import (     "fmt" ) // 將NewInt定義為int類型 type NewInt int // 將int取一個別名叫IntAlias type IntAlias = int func main() {     // 將a聲明為NewInt類型     var a NewInt     // 查看a的類型名     fmt.Printf("a type: %Tn", a)     // 將a2聲明為IntAlias類型     var a2 IntAlias     // 查看a2的類型名     fmt.Printf("a2 type: %Tn", a2) }
        登錄后復制

        代碼運行結果:

        a type: main.NewInt a2 type: int
        登錄后復制

        代碼說明如下:

        • 第 8 行,將 NewInt 定義為 int 類型,這是常見的定義類型的方法,通過 type 關鍵字的定義,NewInt 會形成一種新的類型,NewInt 本身依然具備 int 類型的特性。

        • 第 11 行,將 IntAlias 設置為 int 的一個別名,使用 IntAlias 與 int 等效。

        • 第 16 行,將 a 聲明為 NewInt 類型,此時若打印,則 a 的值為 0。

        • 第 18 行,使用%T格式化參數,打印變量 a 本身的類型。

        • 第 21 行,將 a2 聲明為 IntAlias 類型,此時打印 a2 的值為 0。

        • 第 23 行,打印 a2 變量的類型。

        結果顯示 a 的類型是 main.NewInt,表示 main 包下定義的 NewInt 類型,a2 類型是 int,IntAlias 類型只會在代碼中存在,編譯完成時,不會有 IntAlias 類型。

        非本地類型不能定義方法

        能夠隨意地為各種類型起名字,是否意味著可以在自己包里為這些類型任意添加方法呢?參見下面的代碼演示:

        package main import (     "time" ) // 定義time.Duration的別名為MyDuration type MyDuration = time.Duration // 為MyDuration添加一個函數 func (m MyDuration) EasySet(a string) { } func main() { }
        登錄后復制

        代碼說明如下:

        • 第 8 行,為 time.Duration 設定一個類型別名叫 MyDuration。

        • 第 11 行,為這個別名添加一個方法。

        編譯上面代碼報錯,信息如下:

        cannot define new methods on non-local type time.Duration
        登錄后復制

        編譯器提示:不能在一個非本地的類型 time.Duration 上定義新方法,非本地類型指的就是 time.Duration 不是在 main 包中定義的,而是在 time 包中定義的,與 main 包不在同一個包中,因此不能為不在一個包中的類型定義方法。

        解決這個問題有下面兩種方法:

        • 將第 8 行修改為 type MyDuration time.Duration,也就是將 MyDuration 從別名改為類型;

        • 將 MyDuration 的別名定義放在 time 包中。

        在結構體成員嵌入時使用別名

        當類型別名作為結構體嵌入的成員時會發生什么情況呢?請參考下面的代碼。

        package main import (     "fmt"     "reflect" ) // 定義商標結構 type Brand struct { } // 為商標結構添加Show()方法 func (t Brand) Show() { } // 為Brand定義一個別名FakeBrand type FakeBrand = Brand // 定義車輛結構 type Vehicle struct {     // 嵌入兩個結構     FakeBrand     Brand } func main() {     // 聲明變量a為車輛類型     var a Vehicle         // 指定調用FakeBrand的Show     a.FakeBrand.Show()     // 取a的類型反射對象     ta := reflect.TypeOf(a)     // 遍歷a的所有成員     for i := 0; i < ta.NumField(); i++ {         // a的成員信息         f := ta.Field(i)         // 打印成員的字段名和類型         fmt.Printf("FieldName: %v, FieldType: %vn", f.Name, f.Type.             Name())     } }
        登錄后復制

        代碼輸出如下:

        FieldName: FakeBrand, FieldType: Brand FieldName: Brand, FieldType: Brand
        登錄后復制

        代碼說明如下:

        • 第 9 行,定義商標結構。

        • 第 13 行,為商標結構添加 Show() 方法。

        • 第 17 行,為 Brand 定義一個別名 FakeBrand。

        • 第 20~25 行,定義車輛結構 Vehicle,嵌入 FakeBrand 和 Brand 結構。

        • 第 30 行,將 Vechicle 實例化為 a。

        • 第 33 行,顯式調用 Vehicle 中 FakeBrand 的 Show() 方法。

        • 第 36 行,使用反射取變量 a 的反射類型對象,以查看其成員類型。

        • 第 39~42 行,遍歷 a 的結構體成員。

        • 第 45 行,打印 Vehicle 類型所有成員的信息。

        這個例子中,FakeBrand 是 Brand 的一個別名,在 Vehicle 中嵌入 FakeBrand 和 Brand 并不意味著嵌入兩個 Brand,FakeBrand 的類型會以名字的方式保留在 Vehicle 的成員中。

        如果嘗試將第 33 行改為:

        a.Show()
        登錄后復制

        編譯器將發生報錯:

        ambiguous selector a.Show
        登錄后復制

        在調用 Show() 方法時,因為兩個類型都有 Show() 方法,會發生歧義,證明 FakeBrand 的本質確實是 Brand 類型。

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 日韩欧美一区二区三区中文精品| 亚洲AV无码久久精品蜜桃| 日韩专区亚洲精品欧美专区| 国产精品一区二区不卡| 亚洲av午夜福利精品一区人妖| 国产精品视频色视频| 国产精品666| 国内精品久久人妻互换| 中文国产成人精品久久不卡| 久草视频精品在线| 国产乱子伦精品无码专区| 精品亚洲一区二区| 久久99国产综合精品免费| 亚洲线精品一区二区三区影音先锋| 精品国产香蕉伊思人在线在线亚洲一区二区| 精品视频一区二区三区免费| 国产精品三级国产电影| 无码人妻精品一区二区三区99仓本| 日本精品久久久久影院日本 | 久久精品成人影院| 国产成人精品无人区一区| 久久国产精品-久久精品| 日韩精品乱码AV一区二区| 一区二区国产精品| 亚洲精品宾馆在线精品酒店| 四虎国产精品免费久久| 麻豆国内精品久久久久久 | 亚洲人午夜射精精品日韩| 久久亚洲国产成人精品无码区| 国产精品无码无卡无需播放器| 999国产精品视频| 久久精品国产亚洲欧美| 精品久久久久久国产| 精品久久香蕉国产线看观看亚洲| 国产精品一在线观看| jiucao在线观看精品| 99re国产精品视频首页| 精品国产a∨无码一区二区三区| 精品午夜福利在线观看| 国产日韩精品欧美一区| 国产精品第12页|