go-12.png
12-1.png
大家好闸昨,我叫謝偉蚯斯,是一名程序員。
如何你想要尋找一份和編程相關(guān)的職位饵较,經(jīng)驗(yàn)不太夠的話拍嵌,面試官會(huì)考察你什么?
- 基礎(chǔ)循诉,比如你對某編程語言的理解程度
- 學(xué)習(xí)能力横辆,即如何展現(xiàn)你的學(xué)習(xí)能力
本節(jié)的主題,Go 語言中的:值語義和引用語義
問題列表:
- 值語義和引用語義的區(qū)別是什么茄猫?
- 內(nèi)置的類型哪些是值語義狈蚤,哪些是引用語義?
- make 和 new 有什么區(qū)別划纽?
值語義和引用語義
Go 語言中的大多數(shù)類型都是值語義脆侮。值語義和引用的區(qū)別在于賦值之后,重新賦值勇劣,是否會(huì)改變原值靖避。
如果不改變原值,則是值語義。否則是引用語義筋蓖,引用語義比值語義擁有更復(fù)雜的存儲(chǔ)結(jié)構(gòu)卸耘。比如分配內(nèi)存、指針粘咖、長度蚣抗、容量等。
package main
import "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)
}
結(jié)果:
----: 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]
結(jié)論:
在 Go 語言中值語義和引用語義的區(qū)別發(fā)生在賦值語句中。map讽坏、slice锭魔、channel 這三種類型
賦值之后,修改新的對象路呜,會(huì)改變原對象的內(nèi)容迷捧,是因?yàn)橐谜Z義底層都指向的是地址
引用類型必須使用 make 函數(shù)創(chuàng)建,完成內(nèi)存分配和相關(guān)屬性的初始化胀葱。即:對應(yīng)的值上都有初始化值漠秋,比如 int 類型,則初始化值為0抵屿, 比如 string 類型庆锦,則初始化為空,諸如此類
package main
func main(){
var exampleSlice = make([]int, 4)
exampleSlice[0] = 1
fmt.Println(exampleSlice)
}
結(jié)果:
[1 0 0 0]
只賦值第一個(gè)元素轧葛,其他元素默為0搂抒。
值語義的數(shù)據(jù),想要改變元素值尿扯,需要使用指針:
var exampleInt int
exampleInt = 4
newExampleInt := &exampleInt
*newExampleInt = 40
fmt.Println(exampleInt, *newExampleInt)
結(jié)果:
40 40
內(nèi)置函數(shù) new 按指定類型分配零值內(nèi)存求晶, 返回的是一個(gè)指針。
type Info struct {
Name string
Age int
School string
}
exampleBigInfo := new(Info)
fmt.Println(exampleBigInfo)
結(jié)果:
&{ 0 }
可以看出:
- 返回指針
- 存在零值衷笋,比如 Name 為 '', Age 為0誉帅,School 為 ''.
本節(jié)這樣,再會(huì)右莱。