原文
Go是静态类型的编程语言,变量的类型由存储的值决定,因为数据不能像Python一样动态的分配。
有一个T类型的变量left,可以通过6种方式,把right的值赋值到left边。
1.相同的类型
这是很显然的,当right的类型也是T的时候,这种复制是完全有效的,详见 "Identical types in Go"
2.相同的底层类型
在Go中任何类型都有一个底层类型。像布尔,数字,字符串或者文字类型的基础类型是一样的。除此之外底层类型只能通过一种方式声明:
type X map[string]int
var x X // underlying type is map[string]int
还有一种可以分配的情况是,当有相同的底层类型时:
type X map[string]int
var x X
var y map[string]int
x = y
当有两个声明的类型有相同的底层是,是不能相互赋值的:
type X map[string]int
type Y map[string]int
var x X
var y Y
x = y // cannot use y (type Y) as type X in assignment
也就是说赋值的时候,至少有一个类型不是自己声明的类型。
在Go里面的类型是可命名的也可以是未命名的。未命名的类型可以通过字面指定:
var a [10]string
var b struct{ field string}
var c map[string]int
3.接口赋值给实现了该接口的值
如果变量实现了接口T,那么我们可以把T接口赋值给该变量。
type Callable interface {
f() int
}
type T int
func (t T) f() int {
return int(t)
}
var c Callable
var t T
c = t
更多关于接口类型可以看 language spec
4.当通道的类型相同时,可以相互赋值
type T chan<- map[string]int
var c1 T
var c2 chan map[string]int
c1 = c2
c2 = c1 // cannot use c1 (type T) as type chan map[string]int in assignment
第二种情况有相同的底层类型,但是必须有一个是未命名的类型:
type T chan<- map[string]int
type T2 chan map[string]int
var c1 T
var c2 T2
c1 = c2 // cannot use c2 (type T2) as type T in assignment
5.nil分配
允许将nil分配给指针,函数,切片,映射,通道,接口。
var a *int
var b func(int) int
var c []int
var d map[string]int
var e chan int
var f interface{}
a, b, c, d, e, f = nil, nil, nil, nil, nil, nil
var g [10]int
g = nil // cannot use nil as type [10]int in assignment
6.没有命名类型的常量
可以在Go官方博客里面找到关于Go常量的深度介绍
未分配类型的常量可以赋值给类型为T的变量当常量是T的值。
var a float32
var b float64
var c int32
var d int64
const untyped = 1
a = untyped
b = untyped
c = untyped
d = untyped