完全學會 Go 指針 -- 就要學習 Go 語言

什麼是指針

寫代碼的時候,咱們經過變量就能夠操做存儲在內存中的值,進行賦值、加減運算等。你們有沒有想過,變量表明什麼呢?其實,一個變量對應一段內存空間,這段空間就存儲了該變量相對應類型的值。指針的值就對應變量的地址,只經過指針,就能夠更新或者讀取變量的值,而不須要用到變量名。編程

var i int = 10      //聲明變量i,並初始化爲10
var ptr *int = &i 
fmt.Println(ptr,*ptr)
// 0xc000018060 10 指針變量ptr存儲的是i地址,*ptr對應指針指向的變量的值
*ptr = 12  				// i=12 更新指針指向的變量的值
fmt.Println(*ptr,i)		// 12 12
複製代碼

上面這段代碼,聲明瞭*int 類型的指針變量 ptr ,經過取址運算符&得到指向整型變量 i 的地址。能夠說,指針ptr指向變量i,或者說ptr指針保存了變量i的地址。函數

指針聲明

經過上面一段話的解釋,相信你們對指針有了比較清晰的認識:指針指向一個變量的內存地址。要想使用指針,必須先聲明,格式以下:學習

var var_name *var_type
// var_name 指針名稱,var_type 指針所指向的變量的類型
複製代碼
var i int = 10
str := "go"
var ip *int         // *int類型的指針
var pstr *string    // *string類型的指針
ip = &i
pstr = &str
fmt.Println(*ip,*pstr)     // 10 go
複製代碼

注意*int類型的指針,說明該指針指向的必定是int類型的變量,*string類型也相似。測試

str := "go"
var ip *int
ip = &str  // 編譯不會經過
複製代碼

*int 類型的指針,指向的變量如果string類型的,編譯器編譯的時候就會報錯:ui

cannot use &str (type *string) as type *int in assignment
複製代碼

如何使用指針

文章寫到這裏,關於如何使用指針,其實上文已經列出來了,主要通過三個步驟:聲明賦值訪問指針指向的變量的值spa

x,y := 1,"go"
var px *int = &x    	// 一、聲明並初始化
var py = &y				// 二、省略指針類型,編譯器自動判斷
//px,py := &x,&y // 三、使用 :=
fmt.Println(*px,*py) 	// 1 go 訪問
複製代碼

關於空指針

一個指針已聲明而沒有賦值時,稱爲空指針,爲 nil 。任何類型的指針的零值都是 nil.net

var ip *int
fmt.Println(ip)							// nil
fmt.Printf("ip 的值爲:%x", ip)			// ip 的值爲:0
複製代碼

若是ip != nil 爲真,那麼p是指向某個有效變量。指針之間也是能夠進行相等測試的,只有當它們指向同一個變量或所有是nil時才相等。指針

1、指向同一個變量 true
x,_ := 1,1
px,py := &x,&x
fmt.Println(px == py) 
 
2、指向不一樣變量 false
x,y := 1,1
px,py := &x,&y
fmt.Println(px == py)

3、兩個nil指針 true
var px *int
var py *int
fmt.Println(px == py)
複製代碼

指針做爲函數參數使用

指針包含的是一個變量的地址,若是將一個指針做爲參數傳遞給函數,就能夠經過指針來更新變量的值。code

func a(p *int){
	*p++
}

i := 10
fmt.Println(i)      // 10
a(&i);
fmt.Println(i)		// 11
複製代碼

不經常使用的new函數

給你們介紹下new函數,內建的new函數也是一種建立變量的方法,new(type)表示建立一個type類型的匿名變量,並初始化爲type類型的零值,返回變量的地址,指針類型爲*typecdn

p := new(int)   	// p, *int 類型, 指向匿名的 int 變量
fmt.Println(*p) 	// 0
*p = 2          	// 設置 int 匿名變量的值爲 2
fmt.Println(*p) 	// 2
複製代碼

new函數建立變量和普通變量聲明語句方式建立變量沒有什麼區別,除了不須要聲明一個臨時變量的名字外。 下面的兩個函數有着相同的行爲:建立變量,並返回變量地址

func newA() *int {
    return new(int)
}
func newB() *int {
    var i int
    return &i
}
複製代碼

每次調用new函數都會返回新的變量的地址:

p := new(int)
q := new(int)
fmt.Println(p,q)   // 0xc000018060 0xc000018068
複製代碼

new函數使用的比較少,不過以爲挺有意思的,就在這給你們分享下!實際編程,多的仍是使用具體類型建立變量,畢竟更方便,是吧!


(全文完)

原創文章,若需轉載請註明出處!
歡迎掃碼關注公衆號「Golang來啦」或者移步 seekload.net ,查看更多精彩文章。

公衆號「Golang來啦」給你準備了一份神祕學習大禮包,後臺回覆【電子書】領取!

公衆號二維碼
相關文章
相關標籤/搜索