Go編程語言中的指針是一個變量,用于存儲另一個變量的內(nèi)存地址。Golang中的指針也稱為特殊變量。變量被用于一些數(shù)據(jù)在系統(tǒng)中的一個特定存儲器地址存儲。始終以十六進(jìn)制格式找到內(nèi)存地址(以0x開頭,如0xFFAAF等)。
指針的作用?
要了解這種指針,首先,我們必須了解變量的概念。變量是賦予實際數(shù)據(jù)存儲位置的名稱。要訪問存儲的數(shù)據(jù),我們需要該特定存儲位置的地址。手動記住所有內(nèi)存地址(十六進(jìn)制格式)是一項開銷,這就是為什么我們使用變量來存儲數(shù)據(jù)并且僅通過使用變量名就可以訪問變量的原因。
Golang還允許使用文字表達(dá)式將十六進(jìn)制數(shù)保存到變量中,即,從0x開始的數(shù)字是十六進(jìn)制數(shù)。
示例:在下面的程序中,我們將十六進(jìn)制數(shù)存儲到變量中。但是您可以看到值的類型為int并保存為十進(jìn)制,或者可以說int類型的十進(jìn)制值正在存儲。但是,解釋此示例的主要要點是我們存儲的是十六進(jìn)制值(將其視為內(nèi)存地址),但它不是指針,因為它未指向另一個變量的任何其他內(nèi)存位置。它只是一個用戶定義的變量。因此,這就需要使用指針。
//存儲十六進(jìn)制值
package main
import "fmt"
func main() {
//存儲十六進(jìn)制
//變量中的值
x := 0xFF
y := 0x9C
// 顯示值
fmt.Printf("變量x的類型為 %T\n", x)
fmt.Printf("x的十六進(jìn)制值為 %X\n", x)
fmt.Printf("x的十進(jìn)制值是 %v\n", x)
fmt.Printf("變量y的類型為 %T\n", y)
fmt.Printf("y的十六進(jìn)制值為 %X\n", y)
fmt.Printf("y的十進(jìn)制值是 %v\n", y)
}輸出:
變量x的類型為 int x的十六進(jìn)制值為 FF x的十進(jìn)制值是 255 變量y的類型為 int y的十六進(jìn)制值為 9C y的十進(jìn)制值是 156
指針是一種特殊的變量,它不僅用于存儲其他變量的內(nèi)存地址,而且還指向內(nèi)存的位置,并提供查找存儲在該內(nèi)存位置的值的方法。它通常被稱為特殊類型的變量,因為它幾乎被聲明為變量,但是帶有*(解引用運(yùn)算符)。

在開始之前,我們將在指針中使用兩個重要的運(yùn)算符,即
*運(yùn)算符 也稱為解引用運(yùn)算符,用于聲明指針變量并訪問存儲在地址中的值。
&運(yùn)算符 稱為地址運(yùn)算符,用于返回變量的地址或?qū)⒆兞康牡刂吩L問指針。
聲明一個指針:
var pointer_name *Data_Type
示例:下面是字符串類型的指針,該指針只能存儲字符串變量的內(nèi)存地址。
var s *string
指針的初始化:為此,您需要使用地址運(yùn)算符使用另一個變量的內(nèi)存地址初始化指針,如以下示例所示:
//正常的變量聲明 var a = 45 //用初始化指針s //變量a的內(nèi)存地址 var s *int = &a
// Golang程序來演示聲明
//和指針的初始化
package main
import "fmt"
func main() {
//定義一個正常變量
var x int = 5748
//指針聲明
var p *int
//初始化指針
p = &x
//顯示結(jié)果
fmt.Println("存儲在x中的值 = ", x)
fmt.Println("x的內(nèi)存地址 = ", &x)
fmt.Println("存儲在變量p中的值 = ", p)
}輸出:
存儲在x中的值 = 5748 x的內(nèi)存地址 = 0xc000066090 存儲在變量p中的值 = 0xc000066090
重要事項:
指針的默認(rèn)值或零值始終為nil。 或者,您可以說未初始化的指針將始終具有nil值。
//指針的nil值
package main
import "fmt"
func main() {
//定義指針
var s *int
// 顯示結(jié)果
fmt.Println("s = ", s)
}輸出:
s = <nil>
指針的聲明和初始化可以在一行中完成。
var s *int = &a
如果要同時指定數(shù)據(jù)類型和指針聲明,則指針將能夠處理該指定數(shù)據(jù)類型變量的內(nèi)存地址。例如,如果您使用字符串類型的指針,那么將提供給指針的變量的地址將僅是字符串?dāng)?shù)據(jù)類型變量,而不是其他任何類型。
為了克服上述問題,可以使用var關(guān)鍵字的類型推斷概念。聲明期間無需指定的數(shù)據(jù)類型。指針變量的類型也可以像普通變量一樣由編譯器確定。在這里,我們將不使用*運(yùn)算符。當(dāng)我們使用另一個變量的地址初始化變量時,它將由編譯器內(nèi)部確定。
// Golang程序進(jìn)行演示
//在中使用類型推斷
//指針變量
package main
import "fmt"
func main() {
//使用var關(guān)鍵字
//我們沒有定義
//任何帶變量的類型
var y = 458
//使用指針變量
// var關(guān)鍵字,不指定
//類型
var p = &y
fmt.Println("存儲在y中的值 = ", y)
fmt.Println("y的地址= ", &y)
fmt.Println("存儲在指針變量p中的值 = ", p)
}輸出:
存儲在y中的值 = 458 y的地址= 0xc0000120a8 存儲在指針變量p中的值 = 0xc0000120a8
您也可以使用簡寫(:=)語法來聲明和初始化指針變量。如果我們使用&(address)運(yùn)算符將變量的地址傳遞給它,則編譯器將在內(nèi)部確定該變量為指針變量。
// Golang程序進(jìn)行演示
//在中使用速記語法
//指針變量
package main
import "fmt"
func main() {
//使用:=運(yùn)算符進(jìn)行聲明
//并初始化變量
y := 458
//使用一個指針變量
//通過:=為其分配
//變量y的地址
p := &y
fmt.Println("存儲在y中的值 = ", y)
fmt.Println("y的地址= ", &y)
fmt.Println("存儲在指針變量p中的值 = ", p)
}輸出:
存儲在y中的值 = 458 y的地址= 0xc000066090 存儲在指針變量p中的值 = 0xc000066090
眾所周知,*運(yùn)算符也稱為解引用運(yùn)算符。它不僅用于聲明指針變量,而且還用于訪問指針?biāo)赶虻淖兞恐写鎯Φ闹?,通常將其稱為間接或取消引用。*運(yùn)算符也稱為地址處的值。讓我們舉個實例來更好地理解這個概念:
// Golang程序舉例說明
//解除指針引用的概念
package main
import "fmt"
func main() {
//使用var關(guān)鍵字
//我們沒有定義
//任何帶變量的類型
var y = 458
//使用指針變量
// var關(guān)鍵字,不指定
//類型
var p = &y
fmt.Println("存儲在y中的值 = ", y)
fmt.Println("y的地址= ", &y)
fmt.Println("存儲在指針變量p中的值 = ", p)
//這是取消引用指針
//在指針之前使用*運(yùn)算符
//變量以訪問存儲的值
//指向它所指向的變量
fmt.Println("存儲在y中的值(*p) = ", *p)
}輸出:
存儲在y中的值 = 458 y的地址= 0xc0000120a8 存儲在指針變量p中的值 = 0xc0000120a8 存儲在y中的值(*p) = 458
您也可以更改指針的值或在內(nèi)存的位置,而不是為變量分配新值。
package main
import "fmt"
func main() {
//使用var關(guān)鍵字
//我們沒有定義
//沒有指定變量的類型
var y = 458
//使用指針變量
// var關(guān)鍵字,不指定類型
var p = &y
fmt.Println("更改前存儲在y中的值 = ", y)
fmt.Println("y的地址 = ", &y)
fmt.Println("存儲在指針變量p中的值 = ", p)
//這是取消引用指針
//在指針之前使用*運(yùn)算符
//變量以訪問存儲的值
//指向它所指向的變量
fmt.Println("更改前存儲在y(*p)中的值 = ", *p)
//通過賦值改變y的值
//指針的新值
*p = 500
fmt.Println("更改后存儲在y(*p)中的值 = ", y)
}輸出:
更改前存儲在y中的值 = 458 y的地址 = 0xc0000120a8 存儲在指針變量p中的值 = 0xc0000120a8 更改前存儲在y(*p)中的值 = 458 更改后存儲在y(*p)中的值 = 500