Go语言中Type的多种应用方法

发表时间: 2024-05-03 20:00

type有几种用法:定义结构体, 定义接口, 类型定义, 类型别名, 类型开关

1 定义结构体

结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。类似 Java 的类, 我们可以把Go中的struct看作是不支持继承行为的轻量级的“类”。

我们来看看使用type怎么定义结构体:

package main //必须有个main包import (    "fmt")//定义一个 Books结构体type Books struct {    title string    author string    subject string    book_id int}type person struct {    string    int}//结构体内内嵌匿名成员变量定义func main() {    b := Books{"雍正王朝", "二月河", "康熙和雍正年间的一系列改革事情", 10}    fmt.Println(b.title, b.author, b.subject, b.book_id) //雍正王朝 二月河 康熙和雍正年间的一系列改革事情 10    p := person{"abc", 12}    fmt.Println(p.string, p.int)}

2 定义接口

//定义电话接口type Phone interface {    call()}

3 类型定义

type name string // 类型定义是完全定义了一种新的类型, name 与 string 是不同的数据类型, 传参和赋值要注意数据类型

在这里要区别 var声明方式

var name string //这里是定义一个string变量

实例: 类型定义使用方法

package main //必须有-个main包import "fmt"func main() {    type bigint int64 // 类型定义    var a bigint //等价var a int64    fmt.Printf("a type is %T\n", a)    type (        long int64        char byte    )    var b long = 11    var ch char = 'b'    fmt.Printf("b = %d, ch = %c\n", b, ch)}

实例: 类型定义使用中出现的问题

package main //必须有-个main包import "fmt"func main() {    type bigint int64 // 类型定义    var a bigint //等价var a int64    fmt.Printf("a type is %T\n", a) // a type is main.bigint    var b int64 = 100    // a = b //Error: cannot use b (type int64) as type bigint in assignment    // 解决方法: 使用bigint 转换后 再去赋值 或者 使用类型别名    a = bigint(b)    c := int64(a) // 再次转换    fmt.Println(a, b, c)}

注意: int64 和 bigint 是不同类型, 传值和传参要注意数据类型;

除了给已知的类型起别名, 还可以针对新类型(自定义类型)函数进行定义

type handle func(str string) //自定义一个函数func, 类名叫做handle, 传入一个string参数

实例:

package main//必须有个main包import "fmt"type FuncType func(int, int)int //声明一个函数类型, func后面没有函数名//函数中有一个参数类型为函数类型:fFuncTypefunc Calc(a, b int, f FuncType)(result int){    result = f(a, b)//通过调用f()实现任务    return}func Add(a, b int)int{    return a + b}func Minus(a, b int)int{    return a - b}func main(){    //函数调用,第三个参数为图数名字,此函数的委毅,返回值必须和 FuncType 类型一致    result := Calc(1, 1, Add)    fmt.Println(result) //2    //第二种使用方法    var f FuncType = Minus    fmt.Println("result = ",f(10,2)) //result=8}

4 类型别名

type name = string // name类型与string等价,就是将一个string类型起一个别名叫做name

实例: 使用类型别名

package main //必须有-个main包import "fmt"func main() {//给int64起一个别名叫bigint // 类型别名    type bigint = int64    var a bigint //等价var a int64    fmt.Printf("a type is %T\n", a) // a type is main.bigint    var b int64 = 100    a = b // 直接复制, 类型别名 bigint 与 int64 的数据类型是一致的, 可以直接赋值    c := int64(a) // 再次转换    fmt.Println(a, b, c)}

实例: 非本地类型不能定义方法

package mainimport ("time")// 定义time.Duration的别名为MyDurationtype 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 包中(放置到其他包中)。

6 类型开关

在Go语言中中存在interface{}类型, 可以用来保存任何类型的值, 如果我们需要知道具体保存了哪些类型, 就需要使用类型开关来判断, 具体代码如下:

func classifier(items ...interface{}) {    for i,x := range items {        switch x.(type) {        case bool:            fmt.Printf("type #%d is bool",i)        case float64:            fmt.Printf("type #%d is float64",i)        case string:            fmt.Printf("type #%d is string",i)        case int:            fmt.Printf("type #%d is int",i)        default:            fmt.Printf("type is unknow")        }    }}