go-12.png
12-1.png
大家好,我叫谢伟,是一名程序员。
如何你想要寻找一份和编程相关的职位,经验不太够的话,面试官会考察你什么?
基础,比如你对某编程语言的理解程度
学习能力,即如何展现你的学习能力
本节的主题,Go 语言中的:值语义和引用语义
问题列表:
值语义和引用语义的区别是什么?
内置的类型哪些是值语义,哪些是引用语义?
make 和 new 有什么区别?
值语义和引用语义
Go 语言中的大多数类型都是值语义。值语义和引用的区别在于赋值之后,重新赋值,是否会改变原值。
如果不改变原值,则是值语义。否则是引用语义,引用语义比值语义拥有更复杂的存储结构。比如分配内存、指针、长度、容量等。
package mainimport "fmt"func main() { // map、slice、channel var number int number = 0 copyNumber := number copyNumber = 3 fmt.Printf("----: new=%v, old=%v\n", copyNumber, number) var List = [2]int{1, 2} copyList := List copyList[1] = 4 fmt.Printf("----: new=%v, old=%v\n", copyList, List) type Info struct { Name string Age int School string } oldInfo := Info{ "xieWei", 20, "shanghaiUniversity", } newInfo := oldInfo newInfo.Name = "xieWei2" fmt.Printf("----: new=%v, old=%v\n", newInfo, oldInfo) var Body = make(map[string]string) Body["name"] = "xieWei" Body["School"] = "shanghaiUniversity" newBody := Body newBody["name"] = "xieWei2" newBody["Age"] = "20" fmt.Printf("----: new=%v, old=%v\n", newBody, Body) var oldSlice = []int{1, 2, 3, 4} newSlice := oldSlice newSlice[3] = 10 newSlice = append(newSlice, 100) fmt.Printf("----: new=%v, old=%v\n", newSlice, oldSlice) }
结果:
----: new=3, old=0----: new=[1 4], old=[1 2] ----: new={xieWei2 20 shanghaiUniversity}, old={xieWei 20 shanghaiUniversity} ----: new=map[name:xieWei2 School:shanghaiUniversity Age:20], old=map[name:xieWei2 School:shanghaiUniversity Age:20] ----: new=[1 2 3 10 100], old=[1 2 3 10]
结论:
在 Go 语言中值语义和引用语义的区别发生在赋值语句中。map、slice、channel 这三种类型
赋值之后,修改新的对象,会改变原对象的内容,是因为引用语义底层都指向的是地址
引用类型必须使用 make 函数创建,完成内存分配和相关属性的初始化。即:对应的值上都有初始化值,比如 int 类型,则初始化值为0, 比如 string 类型,则初始化为空,诸如此类
package main func main(){ var exampleSlice = make([]int, 4) exampleSlice[0] = 1 fmt.Println(exampleSlice) }
结果:
[1 0 0 0]
只赋值第一个元素,其他元素默为0。
值语义的数据,想要改变元素值,需要使用指针:
var exampleInt int exampleInt = 4 newExampleInt := &exampleInt *newExampleInt = 40 fmt.Println(exampleInt, *newExampleInt)
结果:
40 40
内置函数 new 按指定类型分配零值内存, 返回的是一个指针。
type Info struct { Name string Age int School string } exampleBigInfo := new(Info) fmt.Println(exampleBigInfo)
结果:
&{ 0 }
可以看出:
返回指针
存在零值,比如 Name 为 '', Age 为0,School 为 ''.
本节这样,再会。
作者:谢小路
链接:https://www.jianshu.com/p/8ca5ef5867cc