Go变量赋值的可传递性

问题描述

网上发现这么一段代码

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
package main
import "fmt"
type I int
type M map[string]interface{}
type M2 map[string]interface{}
func main() {
var m M = M{"hello": "world"}
printM(m) //正常运行
var num I = 123
printI(num) //报错
printM2(m) //报错
}
func printM(m map[string]interface{}) {
fmt.Println(m)
}
func printI(i int) {
fmt.Println(i)
}
func printM2(m M2) {
fmt.Println(m)
}

问题解决

翻查Go语言文档后发现,有这么一段说明

Assignability 可传递性
A value x is assignable to a variable of type T (“x is assignable to T”) if one of the following conditions applies:

  • x’s type is identical to T.
  • x’s type V and T have identical underlying types and at least one of V or T is not a defined type.
  • T is an interface type and x implements T.
  • x is a bidirectional channel value, T is a channel type, x’s type V and T have identical element types, and at least one of V or T is not a defined type.
  • x is the predeclared identifier nil and T is a pointer, function, slice, map, channel, or interface type.
  • x is an untyped constant representable by a value of type T.

翻译下就是

如果满足以下其中一种情况,那么x可以赋值给类型为T的变量

  • x的类型完全等同于T
  • x的类型V和目标类型T有着相同的基本类型且两类型中至少有一个不是defined type
  • T是接口,x实现了该接口
  • x是一个双向通道类型的值,T是一个通道类型,x的类型V和T有相同的元素类型并且V和T中至少一个不是defind type
  • x是nil,T是指针、方法、slice、map、通道或接口类型
  • x是一个可表示为类型T的没有类型的常量

defined type包括所有值类型以及通过type定义的类型
非值类型有map、channel、slice、pointer、函数类型

demo中printM遵循了第二条,所以可以正常赋值

相关资料

文档地址
问题来源