Go 指针
最后修改于 2025 年 5 月 5 日
在本文中,我们将介绍如何在 Golang 语言中使用指针。
在 Go 中,指针 存储的是值的内存地址,而不是值本身。指针的零值为 nil
,表示它尚未引用有效的内存位置。与 C 等语言不同,Go 不支持指针算术,这使得指针管理更安全、更可预测。
指针对于高效处理大型数据结构特别有用,因为传递指针可以避免对大型对象的不必要复制。此外,它们还使函数能够修改其自身作用域之外的数据,这对于基于引用的操作至关重要。
var pv *int = &mysum
在此示例中,pv
被声明为指向整数的指针(*int
)。&
运算符获取变量 mysum
的内存地址并将其分配给 pv
,从而允许间接访问存储的值。
fmt.Println(*pv)
*
运算符用于 解引用 指针,这意味着它会检索所引用内存地址中存储的实际值。通过解引用 pv
,我们访问 mysum
存储的值。
通过使用指针,Go 实现了高效的内存使用,并允许函数直接处理变量而不是副本,从而在某些情况下提高了性能。
Go 指针示例
以下是一个简单的 Go 指针示例。
package main import "fmt" func main() { var count int = 4 fmt.Println(count) var pv = &count *pv = 3 fmt.Println(pv) fmt.Println(*pv) var pv2 *int = &count *pv = 2 fmt.Println(pv2) fmt.Println(*pv2) pv3 := &count *pv = 1 fmt.Println(pv3) fmt.Println(*pv3) }
我们定义了一个 count
整数变量。我们使用三种不同的形式创建了三个指向该变量的指针。
var count int = 4
我们创建了 count
变量。
var pv = &count
我们创建了一个指向 count
变量的指针。
*pv = 3
通过指针解引用,我们修改了 count
的值。
fmt.Println(pv) fmt.Println(*pv)
我们打印 pv
指针的地址和值。
$ go run simple.go 4 0xc0000140f8 3 0xc0000140f8 2 0xc0000140f8 1
Go 指针修改
指针可用于修改其定义函数外部的变量。
package main import "fmt" func modify(pv *int) { *pv = 11 } func main() { var count int = 10 fmt.Println(count) modify(&count) fmt.Println(count) }
在 main
函数内部,我们定义了 count
变量。modify
函数将指针作为参数。我们可以使用它来修改 main
函数外部的 count
变量。默认情况下,Go 中的函数按值传递变量。
$ go run modify.go 10 11
Go 指向结构体的指针
在 Go 中,指针经常与结构体一起使用。
package main import "fmt" type User struct { name string occupation string } func modify(pu *User) { pu.name = "Robert Roe" pu.occupation = "driver" } func main() { u := User{"John Doe", "gardener"} fmt.Println(u) modify(&u) fmt.Println(u) }
我们有一个 User
结构体。我们通过指针在 modify
函数中修改了该结构体。
pu.name = "Robert Roe"
pu.name
与 (*pu).name
相同。
$ go run pstruct.go {John Doe gardener} {Robert Roe driver}
使用 new 关键字的 Go 指针
new
关键字接受一个类型作为参数,分配足够的内存来容纳该类型的值,并返回其指针。
package main import ( "fmt" "reflect" ) type User struct { name string occupation string } func main() { var pu *User = new(User) fmt.Println(pu) fmt.Println(reflect.TypeOf(pu)) pu.name = "Robert Roe" pu.occupation = "accountant" fmt.Println(pu) }
在代码示例中,我们使用 new
关键字创建了一个用户。
$ go run newkey.go &{ } *main.User &{Robert Roe accountant}
Go 指向指针的指针
一个指针可以指向另一个指针。要解引用此类指针的值,我们使用 **
字符。
package main import "fmt" func main() { var a = 7 var p = &a var pp = &p fmt.Println(a) fmt.Println(&a) fmt.Println("--------------------") fmt.Println(p) fmt.Println(&p) fmt.Println("--------------------") fmt.Println(pp) fmt.Println(&pp) fmt.Println("--------------------") fmt.Println(*pp) fmt.Println(**pp) }
该示例创建了一个指向另一个指针 p
的指针 pp
。
$ go run pointer2pointer.go 7 0xc0000140f8 -------------------- 0xc0000140f8 0xc00000e028 -------------------- 0xc00000e028 0xc00000e030 -------------------- 0xc0000140f8 7
来源
The Go Programming Language Specification
在本文中,我们介绍了 Go 指针。