Golang有指針 , 那麼一切數據都是值傳遞嗎 ? 都須要用戶進行指針傳遞嗎, 其實否則, 對於Go語言, 雖然有指針, 可是其也有引用傳遞. 是否是很繞, 由於引用傳遞就是指針傳遞哇 . 咱們繼續解釋.php
在Go語言中,對於布爾變量
或數值類型
或字符串類型
或數組
以及struct
都是按照值傳遞的:值在傳遞給函數或者方法時會被複制一份,而後方法或函數使用的是複製的這份值,也就不會對原值產生什麼影響。通常狀況下,對於布爾變量或數值類型或字符串類型的按值傳遞是很是廉價的,Go語言編譯器會在傳遞過程當中進行安全優化。html
對於大字符串是這樣,對於數組進行值傳遞也是如此。爲了解決可能產生的巨大代價,Go語言使用數組切片來代替數組的使用。傳遞一個切片的代價跟傳遞字符串差很少,不管該切片的長度或容量是多大。對切片進行復制修改操做也不會像字符串那樣須要建立新的切片,由於切片是可變的,屬於引用類型
。java
所以如下就是重點 :數組
語言中的值傳遞類型有:基本數據類型,數組 , struct安全
特色:變量直接存儲值,內存一般在棧中分配,棧在函數調用完會被釋放 , 在調用函數時將實際參數複製一份傳遞到函數中,這樣在函數中若是對參數進行修改,將不會影響到實際參數 , 因此他最大的好處就是不怕多線程安全性問題. 可是浪費內存多線程
Go語言中的引用類型有:映射(map),數組切片(slice),通道(chan),接口(interface) 與 函數(func)。函數
他的變量默認就是指針變量, 因此不須要作&取地址. 你要是花裏胡哨我也無語.優化
特色:變量存儲的是一個地址,這個地址存儲最終的值。內存一般在堆上分配,經過GC回收。所謂引用傳遞是指在調用函數時將實際參數的地址傳遞到函數中,那麼在函數中對參數所進行的修改,將影響到實際參數。引用註定多個線程中共享一個, 容易出現多線程問題,線程
就以引用傳遞和值傳遞區分 , 切記別被下面帶繞了,這種話分析層面不一樣就不同指針
其實在go語言中,只存在值傳遞,本質上,咱們能夠理解函數的傳遞都是值傳遞,只不過引用類型傳遞的是一個指向底層數據的指針,因此咱們在操做的時候,能夠修改共享的底層數據的值,進而影響到全部引用到這個共享底層數據的變量。
操做符& : 是返回該變量的內存地址。
操做符* :是返回該指針指向的變量的值,其實就是解除變量的指針引用,返回該變量的值.
當一個指針被定義後沒有分配到任何變量時,它的值爲 nil。
nil 指針也稱爲空指針。
nil在概念上和其它語言的null、None、nil、NULL同樣,都指代零值或空值。
指針這個玩意, Java裏沒有,其實Java裏確實有指針,咱們無時無刻在使用,下面我舉一個例子
type People struct { name string sex string age int } func main() { var pp *People // 1. 返回一個對象 person1 := People{"zhangsan", "man", 25} fmt.Println(person1) pp=&person1 // 2. 直接實例化一個空對象 , 返回一個指針對象 person2 := new(People) // pp=person2 fmt.Println(*pp) // 2.返回一個指針對象 person3 := &People{"wangwu", "man", 25} pp=person3 fmt.Println(*person3) fmt.Println(*pp) }
輸出
{zhangsan man 25} { 0} {wangwu man 25} {wangwu man 25}
這裏告訴你們一個技巧就是 fmt.Println()
輸出中若是首位是 &
,那麼它必定是一個指針類型的數據 . 可是對於默認的引用對象,不必定了,,,
舉個例子 咱們拿數組爲例子 , 舉例指針的用處
func main() { // 申明數組類型 arr := [3]int{1, 2, 3} // 原數組 fmt.Printf("指針 : %p , 數據 : %v\n", &arr,arr) // 地址傳遞 printSlice(&arr) // 值傳遞 printSlices(arr) // 原數組 fmt.Printf("指針 : %p , 數據 : %v\n", &arr,arr) } func printSlice(arr *[3]int) { // 修改數據 arr[0] = 5 fmt.Printf("指針 : %p , 數據 : %v\n", arr, *arr) } func printSlices(arr [3]int) { // 修改數據 arr[0] = 4 fmt.Printf("指針 : %p , 數據 : %v\n", &arr, arr) }
輸出
指針 : 0xc000052140 , 數據 : [1 2 3] 指針 : 0xc000052140 , 數據 : [5 2 3] 指針 : 0xc0000521c0 , 數據 : [4 2 3] 指針 : 0xc000052140 , 數據 : [5 2 3]