go 切片使用小結
來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。最新項目使用go語言開發,因此有機會結識了go語言。在寫代碼時,無意間發現了同事代碼的一個bug。今天拿來一起學習一下。 首先go語言有個強大的基本資料結構,那就是切片,切片相對於數組更加靈活,動態擴充性極好。而go 語言有個內建函數,叫append,函數原型如下:func append(slice []Type, elems ...Type) []Type,即appen可以對切片追加元素。下面簡單的舉個例子,例子可能會有點硬,希望大家理解。由於訊息互動,需要將元素為int 類型的切片,轉換為 元素為指標類型的切片。 因此有了如下操作:(錯誤方式為原始代碼bug方式簡化版)```gopackage mainimport "fmt"func main() {intSlince := make([]int, 0 )intSlince = append(intSlince,9)intSlince = append(intSlince,8)intSlince = append(intSlince,7)for _ , v := range intSlince{fmt.Println("before convert:",v)}intPtrSlinceA := make([]*int, 0)//錯誤方式//轉換切片元素為指標類型for _ , v := range intSlince{intPtrSlinceA = append(intPtrSlinceA, &v)}//列印切片元素for _ , v := range intPtrSlinceA{fmt.Println("wrong:",*v)}intPtrSlinceB := make([]*int, 0)//正確方式//轉換切片元素為指標類型for i:= range intSlince{intPtrSlinceB = append(intPtrSlinceB, &intSlince[i])}//列印切片元素for _ , v := range intPtrSlinceB{fmt.Println("Right:",*v)}}```運行結果如下:C:/Go\bin\go.exe run E:/go_code/gopath/src/console/append.go```before convert: 9before convert: 8before convert: 7wrong: 7wrong: 7wrong: 7Right: 9Right: 8Right: 7```訊息轉化後,發送出去,在接收端,發現訊息資料異常。 那麼轉化前好的,接收時卻是異常的,說明轉化有問題,再仔細分析上面那段代碼。遍曆整個切片,將元素賦值給臨時變數v,並把v的地址追加到新的切片中去,動作完成。問題出現在 當把第一個值賦值給臨時變數v,並把v的地址追加到新的切片時,那麼新的切片裡存放的是v地址, 值是原切片第一個元素的值, 而當第二個元素變數賦值時,新的切片的第二個元素的地址 仍然是臨時變數v的地址,只不過這個地址存放的值,變成原切片第二個元素的值了,同理,新切片的第一個元素也是v的地址,因此第一個元素裡面存放的值,也跟著變了。 造成的後果就是,轉化後,新切片中所有元素裡面存放的值,都變成了原切片最後一個元素的值。那如何做才能夠解決問題呢?其實我們可以按照正確做法那樣書寫代碼,直接用下標的方式去找對應地址,這樣就不會出錯了。187 次點擊