與數(shù)組的區(qū)別
- 數(shù)組是固定長(zhǎng)度的,而分片確實(shí)可動(dòng)態(tài)增長(zhǎng)的,以定義為例:
// 定義數(shù)組, 一定要指定長(zhǎng)度
var names [5]string
// 定義分片, 不需要指定長(zhǎng)度
var names []string
- 在函數(shù)調(diào)用時(shí), 數(shù)組是值傳遞,而分片是引用傳遞
其實(shí)對(duì)于 golang 來講,函數(shù)調(diào)用的時(shí)候都是值傳遞,拷貝一個(gè)副本, 之所以表現(xiàn)為值傳遞和引用傳遞,在于一個(gè)拷貝的是數(shù)據(jù)值,另一個(gè)拷貝的是數(shù)據(jù)指針,兩個(gè)指針值指向的是同一個(gè)內(nèi)存地址。
分片的實(shí)現(xiàn)
分片的底層數(shù)據(jù)還是使用的數(shù)組,它一共包含 3 個(gè)字段:
- 地址指針
- 長(zhǎng)度
- 容量
// source 是一個(gè)分片, 大小為 4, 容量為: 5
source := make([]string, 4, 5)
fmt.Println(source, len(source), cap(source))
// 輸出: [ ] 4 5
// 注意這里不會(huì)進(jìn)行內(nèi)存分配, 因?yàn)?source 還有剩余空間可以新加數(shù)據(jù)
source = append(source, "1")
fmt.Println(source, len(source), cap(source))
// 輸出: [ 1] 5 5
在使用 append 來為分片添加數(shù)據(jù)時(shí), 是否有內(nèi)存分配很重要
當(dāng) append 沒有內(nèi)存分配時(shí):
source := []string{"1", "2", "3", "4", "5"}
// 拷貝 source 的第二到第三個(gè)元素(不包括第三個(gè))
// copied 的容量包括: 3, 4,5
copied := source[2:3]
fmt.Println("source-->", source)
fmt.Println("copied-->", copied)
fmt.Println("接下來修改 copied 的內(nèi)容,看是否會(huì)對(duì) source 產(chǎn)生影響...")
// 這里 append 內(nèi)部不會(huì)創(chuàng)建一個(gè)新的底層數(shù)組,共有 source 的底層數(shù)組
// 因?yàn)?copied 的容量足夠新加一個(gè)元素
// 所以不會(huì)影響到 source 的內(nèi)容
copied = append(copied, "mike")
fmt.Println("source-->", source)
fmt.Println("copied-->", copied)
輸出:
source--> [1 2 3 4 5]
copied--> [3]
接下來修改 copied 的內(nèi)容,看是否會(huì)對(duì) source 產(chǎn)生影響...
source--> [1 2 3 mike 5]
copied--> [3 mike]
當(dāng) append 有內(nèi)存分配時(shí):
source := []string{"1", "2", "3", "4", "5"}
// 拷貝 source 的第二到第三個(gè)元素(不包括第三個(gè))
// copied 的容量包括: 3
copied := source[2:3:3]
// 此時(shí) copied 會(huì)和 source 共享底層數(shù)組
fmt.Println("source-->", source)
fmt.Println("copied-->", copied)
fmt.Println("接下來修改 copied 的內(nèi)容,看是否會(huì)對(duì) source 產(chǎn)生影響...")
// 這里 append 內(nèi)部會(huì)創(chuàng)建一個(gè)新的底層數(shù)組,不會(huì)共有 source 的底層數(shù)組
// 所以不會(huì)影響到 source 的內(nèi)容
copied = append(copied, "mike")
fmt.Println("source-->", source)
fmt.Println("copied-->", copied)
輸出:
source--> [1 2 3 4 5]
copied--> [3]
接下來修改 copied 的內(nèi)容,看是否會(huì)對(duì) source 產(chǎn)生影響...
source--> [1 2 3 4 5]
copied--> [3 mike]