01_GO语言中级学习之类型(type)

发布于 2022年 04月 01日 09:37

类型别名与类型定义

类型别名

以下代码使用的就是类型别名,例码:

type MyInt2 = int

类型定义

以下代码使用的就是类型定义,例码:

type MyInt1 int

两者区别

使用类型别名时,上例中的 MyInt2 就相当于 int,只是换了个名字,所以以下代码是不会报错的:

type MyInt2 = int
func main() {
    var i int =0
    var i1 MyInt2 = i 
}

但是使用类型定义时,就需要注意,看例码:

type MyInt1 int
func main() {
    var i int =0
    var i1 MyInt1 = i // 这里编译不通过,需要进行强转,像下边行一样
    var i1 MyInt1 = MyInt1(i)
}

命名类型 和 未命名类型

Go 中的类型可以分为命名类型(named type) 和 未命名类型(unnamed type)。

问题提出

由上边的知识点我们可以知道,下边代码编译是不通过的:

type MyInt1 int
func main() {
    var i int =0
    var i1 MyInt1 = i // 这里编译不通过
}

但是下边的这种情况又是可以通过编译的:

type MyMap1 map[string]string
func main() {
    var myMap = map[string]string{"name": "shalom"}
    var myMap1 MyMap1 = myMap // 注意这一行
    fmt.Println(myMap1)
}

这个原因就和 命令类型 未命名类型 有关。

命名类型

命名类型包括 bool、int、string 等

未命名类型

array、slice、map 等和 具体元素类型长度 等有关的,属于未命名类型。

上述问题的答案

具有 相同声明的未命名类型 被视为同一类型。如:

  • 具有相同基类型的指针。
  • 具有相同元素类型和⻓度的 array。
  • 具有相同元素类型的 slice(注意slice没有包含长度)。
  • ……

命名类型 和 非命名类型 可以相互赋值,只要基础类型一样就可以。

map[string]string 属于未命名类型,他可以和 MyMap1 相互赋值,因为他们的基础类型一样。

常见坑

下边这道题包含了上边两部分的知识:

package main
import (
    "fmt"
)
func main() {
    type MyMap1 map[string]string
    type MyMap2 map[string]string
    var myMap = map[string]string{"name": "polaris"}
    var myMap1 MyMap1 = myMap
    var myMap2 MyMap2 = myMap1  // 此处会报错
    fmt.Println(myMap2)
}
  1. type MyMap map[string]string 规定了元素的类型必须是string,不能再更改,所以就属于命名类型;
  2. 既然属于命名类型,那么第二题中的 MyMap1 MyMap2就是两个不同类型,不能够相互赋值;
  3. 命名类型 和 非命名类型 可以相互赋值,只要基础类型一样就可以。

推荐文章