zoukankan      html  css  js  c++  java
  • Go语言之Go 语言类型别名

    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() {
    	var a NewInt
    	fmt.Printf("a type: %T
    ", a)
    
    	var b IntAlias
    	fmt.Printf("b type: %T
    ", b)
    
    }
    
    
    结果:
    a type: main.NewInt  
    b type: int      
    
    分析:
     1、NewInt 定义为 int 类型,这是常见的定义类型的方法,通过 type 关键字的定义,NewInt 会形成一种新的类型,NewInt 本身依然具备 int 类型的特性。
     2、将 IntAlias 设置为 int 的一个别名,使用 IntAlias 与 int 等效。
     3、将 a 声明为 NewInt 类型,此时若打印,则 a 的值为 0
     4、将 b 声明为 IntAlias 类型,此时打印 b 的值为 0。
     
     结果显示 a 的类型是 main.NewInt,表示 main 包下定义的 NewInt 类型 b 类型是 int,IntAlias 类型只会在代码中存在,编译完成时,不会有 IntAlias 类型
    

    非本地类型不能定义方法

    package main
    import (
        "time"
    )
    // 定义time.Duration的别名为MyDuration
    type MyDuration = time.Duration
    // 为MyDuration添加一个函数
    func (m MyDuration) EasySet(a string) {
    }
    func main() {
    }
    time.Duration 设定一个类型别名叫 MyDuration
    为这个别名添加一个方法。
    
    

    编译上面代码报错,信息如下:

    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
    ", 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 的成员中。

    a.Show()

    编译器将发生报错:

    ambiguous selector a.Show

    在调用 Show() 方法时,因为两个类型都有 Show() 方法,会发生歧义,证明 FakeBrand 的本质确实是 Brand 类型。

  • 相关阅读:
    jquery easyui DataGrid
    easyui datagrid使用
    easyui中datagrid用法,加载table数据与标题
    目前已有的框架
    CSS 块级元素、内联元素概念
    设计中最常用的CSS选择器
    ASP.NET MVC 学习
    CSS边框-属性详解
    Boostrap入门级css样式学习
    Codeforces Round #261 (Div. 2)——Pashmak and Graph
  • 原文地址:https://www.cnblogs.com/heych/p/12577532.html
Copyright © 2011-2022 走看看