Go:type关键词总结

Go:type关键词总结

type关键词总结

type 用法:

  • 定义结构体
  • 定义接口
  • 类型别名
  • 类型定义
  • 类型开关

类型定义和类型别名的区别:
区别就是类型定义是完全定义了一种新的类型,
而类型别名只是给现有的类型取了一个别名alias。(编译器会替换成基本类型。)

Type常见Demo

定义结构体
1
2
type Demo struct {}

定义接口
1
2
type Demoer interface {}

类型别名
1
2
type Demo string

类型定义
1
2
type handle func(str string) 

类型开关
1
2
3
4
5
6
7
8
9
10
11
func Demo(params ...interface{})  {
for i, x := range params {
switch x.(type) {
case bool:
fmt.Printf("type #%d is bool",i)
default:
fmt.Printf("type is unknow")
}
}
}

类型注意事项

类型比较

备注:
参考Go文档type说明:

  • 命名类型(简单类型),有类型名称如 int, int64, float, string, bool. 还有自定义的命名类型。

  • 非命名类型(复杂类型),没类型名称 array slice, map,func(){}, interface{}。但是chan类型是可以==比较

    • slice 内存不连续,底层对象分开放的,不能直接比较;
    • map 内存不连续,底层对象独立存放,不能直接比较;
    • chan 内存是连续的,单一对象,可以直接比较;
  • 当比较两个命名类型的时候,类型名称必须一样;当比较命名类型和非命名类型的时候,底层类型一样即可

  • 比较基于两个原则:1.内存底层基本类型;2.类型本身是否确定类型或不稳定类型;

  • 空接口值比较

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package main

import (
"fmt"
"reflect"
)

type T1 []string
type T2 []string

func main() {
foo0 := []string{}
foo1 := T1{}
foo2 := T2{}
fmt.Println(reflect.TypeOf(foo0))
fmt.Println(reflect.TypeOf(foo1))
fmt.Println(reflect.TypeOf(foo2))

// Output:
// []string
// main.T1
// main.T2

//编译通,反之亦然
//foo1 = foo0
//foo0 = foo1

// 编译不通过
// 错误提示:cannot use foo2 (type T2) as type T1 in assignment
foo2 = foo0
foo1 = foo2 //cannot



//编译通过:chan
ch1 := make(chan int)
ch2 := make(chan int)
fmt.Println(ch1 == ch2)

//编译不通过:slice
s1 := []int{1,2}
s2 := []int{2,1}
fmt.Println(s1 == s2)

//编译不通过:map
m1 := make(map[int]int)
m2 := make(map[int]int)
fmt.Println(m1 == m2)
}

类型可比较性

判断原则:
底层数据结构类型是否稳定和一致

类型说明
map宕机错误,不可比较
切片([]T)宕机错误,不可比较
通道(channel)可比较,必须由同一个 make 生成,也就是同一个通道才会是 true,否则为 false
数组([容量]T)可比较,编译期知道两个数组是否一致
结构体可比较,可以逐个比较结构体的值
函数可比较
Author

Jack Liu

Posted on

2020-02-27

Updated on

2024-02-17

Licensed under