Go語言指針

指針簡介

(Pointer)是編程語言中的一個對象,利用地址,它的值直接指向(points to)存在電腦存儲器中另外一個地方的值。因爲經過地址能找到所需的變量單元,能夠說,地址指向該變量單元。所以,將地址形象化的稱爲「指針」。意思是經過它能找到以它爲地址的內存單元。一個指針變量指向了一個值的內存地址。編程

 

Go語言支持指針類型*T,指針的指針**T,以及包含包名前綴的*package.T安全

指針聲明

在指針類型變量前面加上 *(取值符)來獲取指針所指向的內容。
在值類型變量前面加上 &(取地址符)來獲取該變量的指針。
編程語言

聲明一個int值的指針變量ui

var ip *int

聲明一個string值的指針變量spa

var sp *string

經過 := 語法來定義指針指針

var str string = "春生"
sp := &str

聲明一個int值的指針的指針變量code

var p **int

聲明一個time.Time值的指針變量對象

var t *time.Time

打印變量在內存中的地址:blog

package main

import "fmt"

func main() {
    var str string = "oldboy"

    fmt.Printf("變量的地址: %x\n", &str)
}

運行結果:ip

變量的地址: c42000e1d0

空指針

當一個指針被定義後沒有分配到任何變量時,它的值爲 nil。nil 指針也稱爲空指針。

nil在概念上和其它語言的null、None、nil、NULL同樣,都指代零值或空值。

package main

import (
    "fmt"
)

func main() {
    var ip *int
    var sp *string

    if ip == nil {
        fmt.Println("ip == nil")
    }
    if sp == nil {
        fmt.Println("sp == nil")
    }
}

定義的不一樣類型的零值不能用於比較運算,實例以下:

package main

import (
    "fmt"
)

func main() {
    var ip *int
    var sp *string

    if ip == sp {
        fmt.Println("error")
    }
}

編譯錯誤:

./main.go:11:8: invalid operation: ip == sp (mismatched types *int and *string)

查看零值指針類型,實例以下:

package main

import (
    "fmt"
)

func main() {
    var ip *int
    var sp *string

    fmt.Printf("ip : %#v\n", ip)
    fmt.Printf("sp : %#v\n", sp)
}

運行結果:

ip : (*int)(nil)
sp : (*string)(nil)

指針類型轉換

Go語言是不容許兩個指針類型進行轉換的。

咱們通常使用T做爲一個指針類型,表示一個指向類型T變量的指針。爲了安全的考慮,兩個不一樣的指針類型不能相互轉換,好比 *uint 不能轉爲 *int 。實例以下:

package main

func main() {
    var i uint = 10
    var p2 *int

    p1 := &i
    p2 = (*int)(p1)
}

編譯錯誤:

./main.go:8:13: cannot convert p1 (type *uint) to type *int

unsafe.Pointer類型用於表示任意類型的指針。有4個特殊的只能用於Pointer類型的操做:

一、 任意類型的指針能夠轉換爲一個Pointer類型值
二、 一個Pointer類型值能夠轉換爲任意類型的指針
三、 一個uintptr類型值能夠轉換爲一個Pointer類型值
四、 一個Pointer類型值能夠轉換爲一個uintptr類型值

所以,Pointer類型容許程序繞過類型系統讀寫任意內存。使用它時必須謹慎。實例以下:

package main

import (
    "fmt"
    "unsafe"
)

func main() {
    var i uint = 10
    var p2 *int

    p1 := &i
    p2 = (*int)(unsafe.Pointer(p1))
    fmt.Println(*p2)
}
相關文章
相關標籤/搜索