首頁 後端開發 Golang Go語言型別別名是什麼

Go語言型別別名是什麼

Jan 10, 2023 pm 05:58 PM
golang 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定義類型別名使用的關鍵字。
TypeAliasType 的別名。
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: %T\n", a)
    // 将a2声明为IntAlias类型
    var a2 IntAlias
    // 查看a2的类型名
    fmt.Printf("a2 type: %T\n", 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: %v\n", 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 类型。

【相关推荐:Go视频教程编程教学

以上是Go語言型別別名是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Go的爬蟲Colly中Queue線程的問題是什麼? Go的爬蟲Colly中Queue線程的問題是什麼? Apr 02, 2025 pm 02:09 PM

Go爬蟲Colly中的Queue線程問題探討在使用Go語言的Colly爬蟲庫時,開發者常常會遇到關於線程和請求隊列的問題。 �...

Go語言中用於浮點數運算的庫有哪些? Go語言中用於浮點數運算的庫有哪些? Apr 02, 2025 pm 02:06 PM

Go語言中用於浮點數運算的庫介紹在Go語言(也稱為Golang)中,進行浮點數的加減乘除運算時,如何確保精度是�...

在 Go 語言中,為什麼使用 Println 和 string() 函數打印字符串會出現不同的效果? 在 Go 語言中,為什麼使用 Println 和 string() 函數打印字符串會出現不同的效果? Apr 02, 2025 pm 02:03 PM

Go語言中字符串打印的區別:使用Println與string()函數的效果差異在Go...

Go語言中`var`和`type`關鍵字定義結構體的區別是什麼? Go語言中`var`和`type`關鍵字定義結構體的區別是什麼? Apr 02, 2025 pm 12:57 PM

Go語言中結構體定義的兩種方式:var與type關鍵字的差異Go語言在定義結構體時,經常會看到兩種不同的寫法:一�...

Go語言中哪些庫是由大公司開發或知名的開源項目提供的? Go語言中哪些庫是由大公司開發或知名的開源項目提供的? Apr 02, 2025 pm 04:12 PM

Go語言中哪些庫是大公司開發或知名開源項目?在使用Go語言進行編程時,開發者常常會遇到一些常見的需求,�...

在Go語言中使用Redis Stream實現消息隊列時,如何解決user_id類型轉換問題? 在Go語言中使用Redis Stream實現消息隊列時,如何解決user_id類型轉換問題? Apr 02, 2025 pm 04:54 PM

Go語言中使用RedisStream實現消息隊列時類型轉換問題在使用Go語言與Redis...

GoLand中自定義結構體標籤不顯示怎麼辦? GoLand中自定義結構體標籤不顯示怎麼辦? Apr 02, 2025 pm 05:09 PM

GoLand中自定義結構體標籤不顯示怎麼辦?在使用GoLand進行Go語言開發時,很多開發者會遇到自定義結構體標籤在�...

VSCode中如何解決Golang泛型函數類型約束被自動刪除的問題? VSCode中如何解決Golang泛型函數類型約束被自動刪除的問題? Apr 02, 2025 pm 02:15 PM

VSCode中Golang泛型函數類型約束的自動刪除問題在使用VSCode編寫Golang代碼時,用戶可能會遇到一個奇怪的問題。當...

See all articles