值语义和引用语义的差别在于赋值,比如下面的例子:
b=a
b.Modify()
如果b的修改不会影响a的值,那么此类型属于值类型。
如果会影响a的值,那么此类型是引用 类型。
Go语言中的大多数类型都基于值语义,包括:
基本类型,如byte、int、bool、float32、float64和string等;
复合类型,如数组(array)、结构体(struct)和指针(pointer)等。
Go语言中类型的值语义表现得非常彻底。我们之所以这么说,是因为数组。
Go语言中的数组和基本类型没有区别,是很纯粹的值类型,例如:
var a = [3]int{1, 2, 3}
var b = a
b[1]++
fmt.Println(a, b)
// 该程序的运行结果如下:
[1 2 3] [1 3 3]。
这表明b=a赋值语句是数组内容的完整复制。要想表达引用,需要用指针:
var a = [3]int{1, 2, 3}
var b = &a
b[1]++
fmt.Println(a, *b)
// 该程序的运行结果如下:
[1 3 3] [1 3 3]
这表明b=&a赋值语句是数组内容的引用。变量b的类型不是[3]int,而是*[3]int类型。