类型别名与类型定义
类型别名
以下代码使用的就是类型别名,例码:
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)
}
-
type MyMap map[string]string
规定了元素的类型必须是string,不能再更改,所以就属于命名类型; - 既然属于命名类型,那么第二题中的
MyMap1 MyMap2
就是两个不同类型,不能够相互赋值; - 命名类型 和 非命名类型 可以相互赋值,只要基础类型一样就可以。