golang讀取文件的幾種方法?文章快查Golang越學越難之引用陷阱(一),現在小編就來說說關于golang讀取文件的幾種方法?下面内容希望能幫助到你,我們來一起看看吧!
文章快查
Golang越學越難之引用陷阱(一)
前言看過上篇文章的同學可以得知,在同定義域内調用append進行元素追加,若沒有正确的對象進行接收,是存在引用風險的。
本文将結合實際案例,繼續探究以Slice為典型引用類型代表的陷阱。
問題一在日常研發工作中,大家經常會寫出這麼一段代碼:
func main() {
//創建一個長度和容量均為3的切片
arr := []int{1,2,3}
fmt.Println(arr) // [1 2 3]
//-------
addNum(arr)
//-------
fmt.Println(arr) // [1,2,3]
}
func addNum(sli []int){
//使用appedn添加"4"
sli = append(sli, 4)
fmt.Println(sli) // [1,2,3,4]
}
有同學可能會感到疑惑,為什麼已經使用了sli對append返回的切片進行接收,在main函數中還是沒能打印出來?
那麼我們接着看:
func main() {
arr := []int{1,2,3}
fmt.Printf("%p\n",arr) //0xc000014150
//-------
addNum(arr)
//-------
fmt.Printf("%p\n",arr) //0xc000014150
}
func addNum(sli []int){
sli = append(sli, 4)
fmt.Printf("%p\n",sli) //0xc00000c360
}
是不是有種恍然大悟的感覺。從輸出結果可知,拷貝切片指針發生改變,而原指針并沒有變化。
問題二此時創建一個長度為3,容量為4的切片,并再次使用append方法在函數中對切片進行添加操作。
func main() {
arr := make([]int,3,4)//創建一個長度為3,容量為4的切片
fmt.Printf("%p\n",arr) //0xc000012200
// -----
addNum(arr)
// -----
fmt.Printf("%p\n",arr) //0xc000012200
}
func addNum(sli []int){
sli = append(sli, 4)
fmt.Printf("%p\n", sli) //0xc000012200
}
從結果可以看出,因為初始時,已經設置了切片的容量為4,所以拷貝切片并沒有因為擴容指向新的數組。
那此時原切片是否會發生改變?
func main() {
arr := make([]int, 3, 4) //創建一個長度為3,容量為4的切片
fmt.Printf("%p\n", arr) //0xc000012200
fmt.Println(arr) //[0 0 0]
// -------
addNum(arr)
// -------
fmt.Printf("%p\n", arr) //0xc000012200
fmt.Println(arr) //[0 0 0]
}
func addNum(sli []int) {
sli = append(sli, 4)
fmt.Printf("%p\n", sli) //0xc000012200
fmt.Println(sli) //[0 0 0 4]
}
從代碼運行結果可以看出,原切片并沒有發生改變。
因為,雖然原切片的底層數組發生了變化,但長度Len沒有發生變化,因此原切片的值仍然不變。
看官方怎麼說In a function call, the function value and arguments are evaluated in the usual order. After they are evaluated, the parameters of the call are passed by value to the function and the called function begins execution.
官方很隐晦的給出了Golang中并沒有引用傳遞的概念,Golang是不存在引用傳遞的。
但網上有很多的說法,最多的是slice,map和chan作為參數傳遞到函數中時是傳的引用,其實這個說法不準确,我們不能單純因為函數内部的修改可以反饋到外面就認為是傳遞的引用。
小結(1)當未擴容時,原切片底層數組改變,但是在原切片結構體中Len參數是值傳遞,所以不會影響外部切片,故在内部修改而外部不可見;
(2)當發生擴容時,生成新切片對象,切片地址改變,故而外部切片地址不變(舊切片),故而也不可見。
(3) Go語言中不存在引用類型。
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!