【Go Time】Go語言 指針詳解

什麼是指針

請關注原做者公衆號:Go編程時光程序員

當咱們定義一個變量 nameshell

var name string = "Go指針"

此時,name 是變量名,它只是編程語言中方便程序員編寫和理解代碼的一個標籤。編程

當咱們訪問這個標籤時,計算機會返回給咱們它指向的內存地址裏存儲的值:Go指針數組

出於某些須要,咱們會將這個內存地址賦值給另外一個變量名,一般叫作prt(pointer的簡寫),而這個變量,咱們稱之爲指針變量。編程語言

換句話說,指針變量(一個標籤)的值是指針,也就是內存地址。函數

根據變量指向的值,是不是內存地址,把變量分爲兩種:指針

  • 普通變量:存數據值自己
  • 指針變量:存值的內存地址

指針的建立

指針建立有三種方法code

第一種方法內存

先定義對應的變量,再經過變量取得內存地址,建立指針字符串

// 定義普通變量
aint := 1
// 定義指針變量
ptr := &aint

第二種方法

先建立指針,分配好內存後,在給指針指向的內存地址寫入對應的值

// 建立指針
astr := new(string)
// 給指針賦值
*astr = "Go指針"

第三種方法

先聲明一個指針變量,再從其餘變量取得內存地址賦值給它

aint := 1
var bint *int // 聲明一個指針
bint = &aint

上面三段代碼中,指針的操做都離不開這兩個符號:

  • &:從一個普通變量中取得內存地址
  • *:當*在賦值操做值得右邊,從一個指針變量中取得變量值,當*在賦值操做值得左邊,是指該指針指向的變量

經過下面這段代碼,你能夠熟悉這兩個符號的用法

package main

import "fmt"

func main(){
    aint := 1 // 定義普通變量
    ptr := &aint // 定義指針變量
    fmt.Println("普通變量存儲的是:",aint)
    fmt.Println("普通變量存儲的是:",*ptr)
    fmt.Println("指針變量存儲的是:",&aint)
    fmt.Println("指針變量存儲的是:",ptr)
}

輸出以下

普通變量存儲的是:1
普通變量存儲的是:1
指針變量存儲的是:0xc0000100a0
指針變量存儲的是:0xc0000100a0

要想打印指針指向的內存地址,方法有兩種

// 第一種
fmt.Printf("%p",ptr)

//第二種
fmt.Println(ptr)

指針的建立

咱們知道字符串的類型是 string,整型是 int,那麼指針如何表示呢?

package main

import "fmt"

func main() {
    astr := "hello"
    aint := 1
    abool := false
    arune := 'a'
    afloat := 1.2
    
    fmt.Printf("asgr 指針類型是:%T\n", &astr)
    fmt.Printf("aint 指針類型是:%T\n", &aint)
    fmt.Printf("abool 指針類型是:%T\n", &abool)
    fmt.Printf("arune 指針類型是:%T\n", &arune)
    fmt.Printf("afloat 指針類型是:%T\n", &afloat)
}

輸入以下,能夠發現用 * + 所指向變量值的數據類型,就是對應的指針類型。

astr 指針類型是:*string
aint 指針類型是:*int
abool 指針類型是:*bool
arune 指針類型是:*int32
afloat 指針類型是:*float

因此若咱們定義一個只接收指針類型的參數的函數,能夠這麼寫

func mytest(ptr *int) {
    fmt.Println(*ptr)
}

指針的零值

當指針聲明後,沒有進行初始化,其零值是 nil。

func main() {
    a := 25
    var b *int // 聲明一個指針
    
    if b == nil {
        fmt.Println(b) // <nil>
        b = &a // 初始化:將a的內存地址給b
        fmt.Println(b) // 0xc0000100a0
    }
}

指針與切片

切片與指針同樣,都是引用類型。

若是咱們想經過一個函數改變一個數組的值,有兩種方法

  1. 將這個數組的切片做爲參數傳給函數
  2. 將患者數組的指針做爲參數傳給函數

儘管兩者均可以實現咱們的目的,可是按照Go語言的使用習慣,建議使用第一種方法,由於第一種方法,寫出來的代碼更簡潔,易懂。

使用切片

func modify(sls []int) {
    sls[0] = 90
}

func main() {
    a := [3]int{89,90,91}
    modify(&a)
    fmt.Println(a)
}

使用指針

func modify(arr *[3]int) {
    (*arr)[0] = 90
}

func main() {
    a := [3]int{89,909,1}
    modify(&a)
    fmt.Println(a)
}
相關文章
相關標籤/搜索