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
值,以防指標沒有確切的地址分配。這是在變數宣告的時候完成的。指定為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允許有指標指向指標等等 |
傳遞指標到函式 | 通過參照或地址傳遞引數都允許被呼叫函式在呼叫函式中更改傳遞的引數。 |