Go中的指針是很容易學習,也是比較有趣的。一些Go編程任務使用指針更容易執行,並且不使用指針不能執行其他任務,例如通過引用調用。 因此,有必要學習指針,成為一個完美的Go程式員。現在我們開始通過簡單和容易的步驟來學習Go編程中的指針。
如眾所知,每個變數都是一個記憶體位置,每個記憶體位置都有其定義的地址,可以使用”和”號(&)運算符來訪問它,這個運算符表示記憶體中的地址。參考下麵的例子,它將列印定義的變數的地址:
package main
import "fmt"
func main() {
var a int = 10
fmt.Printf("Address of a variable: %x\n", &a )
}
當上面的代碼被編譯和執行時,它產生結果如下:
Address of a variable: 10328000
所以要明白什麼是記憶體地址,以及如何訪問它,基礎的概念講到這裏就結束了。現在讓我們看看什麼是指針。
什麼是指針?
指針是一個變數,其值是另一個變數的地址,即記憶體位置的直接地址。類似變數或常量一樣,必須要先聲明一個指針,然後才能使用它來存儲任何變數地址。指針變數聲明的一般形式是:
var var-name *var-type
這裏,var-type
是指針的基類型; 它必須是有效的Go數據類型,var-name
是指針變數的名稱。用於聲明指針的星號(*
)與用於乘法的星號相同。但是,在此語句中,星號(*
)用於將變數指定為指針。以下是有效的指針聲明:
var ip *int /* pointer to an integer */
var fp *float32 /* pointer to a float */
所有指針的值的實際數據類型(無論是整數,浮點數還是其他數據類型)都是相同的,它表示記憶體地址的長十六進制數。不同數據類型的指針的唯一區別是指針所指向的是變數或常量的數據類型。
如何使用指針?
有幾個重要的操作,將非常頻繁地使用指針來實現。
- 定義一個指針變數
- 將一個變數的地址賦值給一個指針
- 最後訪問指針變數中可用地址的值
這是通過使用一元運算符*
來返回位於運算元指定的地址的變數的值。下麵的例子使用這些操作:
package main
import "fmt"
func main() {
var a int= 20 /* actual variable declaration */
var ip *int /* pointer variable declaration */
ip = &a /* store address of a in pointer variable*/
fmt.Printf("Address of a variable: %x\n", &a )
/* address stored in pointer variable */
fmt.Printf("Address stored in ip variable: %x\n", ip )
/* access the value using the pointer */
fmt.Printf("Value of *ip variable: %d\n", *ip )
}
當上面的代碼編譯和執行時,它產生結果如下:
Address of var variable: 10328000
Address stored in ip variable: 10328000
Value of *ip variable: 20
在Go語言中的nil指針
Go編譯器為指針變數分配一個Nil
值,以防指針沒有確切的地址分配。這是在變數聲明的時候完成的。指定為nil
值的指針稱為nil
指針。
nil
指針是在幾個標準庫中定義的值為零的常量。參考下麵的程式:
package main
import "fmt"
func main() {
var ptr *int
fmt.Printf("The value of ptr is : %x\n", ptr )
}
當上面的代碼編譯和執行時,它產生結果如下:
The value of ptr is 0
在大多數操作系統上,程式不允許訪問地址0
處的記憶體,因為該記憶體是由操作系統保留的。 然而,記憶體地址0
具有特殊意義; 它表示指針不打算指向可訪問的記憶體位置。但是按照慣例,如果指針包含nil
(零)值,則假設它不指向任何東西。
要檢查是否為nil
指針,可以使用if
語句,如下所示:
if(ptr != nil) /* succeeds if p is not nil */
if(ptr == nil) /* succeeds if p is null */
有關指針的詳細資訊
指針有很多但很簡單的概念,它們對Go編程非常重要。下麵幾個重要的指針概念,對於Go程式員應該要清楚:
概念 | 描述 |
---|---|
Go指針數組 | 可以定義數組來保存一些指針 |
Go指針的指針 | Go允許有指針指向指針等等 |
傳遞指針到函數 | 通過引用或地址傳遞參數都允許被調用函數在調用函數中更改傳遞的參數。 |