Go 中的指针允许我们直接操作内存地址。例如,我们可以使用指针访问和修改内存中变量的值。
在学习指针之前,让我们先了解一下 Golang 中的内存地址。
内存地址
当我们创建一个变量时,会为其分配一个内存地址来存储该变量的值。
在 Go 中,我们可以使用 &
运算符来访问内存地址。例如:
// Program to illustrate how memory address works
package main
import "fmt"
func main() {
var num int = 5
// prints the value stored in variable
fmt.Println("Variable Value:", num)
// prints the address of the variable
fmt.Println("Memory Address:", &num)
}
输出
Variable Value: 5 Memory Address: 0xc000018030
在上面的示例中,我们创建了变量 num,其值为 5。请注意打印语句
fmt.Println("Memory Address:", &num)
这里,&num
访问存储 num 变量的内存地址。
Go 指针变量
在 Go 中,我们使用指针变量来存储内存地址。例如:
var num int = 5
// create the pointer variable
var ptr *int = &num
这里,我们创建了一个名为 ptr 的指针变量,它存储了 num 变量的内存地址。
*int
表示该指针变量是 int
类型(存储 int
变量的内存地址)。
我们也可以创建其他类型的指针变量。例如:
// pointer variable of string type
var ptr1 *string
// pointer variable of double type
var ptr2 * float32
现在让我们看一个指针的实际工作示例。
示例:指针变量
我们可以将一个变量的内存地址赋给一个指针变量。例如:
// Program to assign memory address to pointer
package main
import "fmt"
func main() {
var name = "John"
var ptr *string
// assign the memory address of name to the pointer
ptr = &name
fmt.Println("Value of pointer is", ptr)
fmt.Println("Address of the variable", &name)
}
输出
Value of pointer is 0xc00007c1c0 Address of the variable 0xc00007c1c0
在上面的示例中,我们创建了一个名为 ptr 的 string
类型指针变量。这里,指针变量和 name 变量的地址是相同的。
这是因为指针 ptr 存储了 name
变量的内存地址。
ptr = &name
获取 Golang 中指针指向的值
我们使用 *
运算符来访问指针指向的内存地址中的值。例如:
// Program to get the value pointed by a pointer
package main
import "fmt"
func main() {
var name = "John"
var ptr *string
ptr = &name
// * to get the value pointed by ptr
fmt.Println(*ptr) // John
}
这里,我们使用 *ptr
来访问指针指向的内存地址中存储的值。
由于指针存储了 name 变量的内存地址,因此我们得到输出值 "John"。
注意:在上面的示例中,ptr 是一个指针,而 *ptr
不是。您不能也不应该这样做 *ptr = &name
*
被称为解引用运算符(在处理指针时)。它作用于指针并给出该指针中存储的值。
示例:Golang 中指针的工作原理
package main
import "fmt"
func main() {
var num int
var ptr *int
num = 22
fmt.Println("Address of num:",&num)
fmt.Println("Value of num:",num)
ptr = &num
fmt.Println("\nAddress of pointer ptr:",ptr)
fmt.Println("Content of pointer ptr:",*ptr)
num = 11
fmt.Println("\nAddress of pointer ptr:",ptr)
fmt.Println("Content of pointer ptr:",*ptr)
*ptr = 2
fmt.Println("\nAddress of num:",&num)
fmt.Println("Value of num:",num)
}
输出
Address of num: 0xc000090020 Value of num: 22 Address of pointer ptr: 0xc000090020 Content of pointer ptr: 22 Address of pointer ptr: 0xc000090020 Content of pointer ptr: 11 Address of num: 0xc000090020 Value of num: 2
说明:Go 指针的工作原理
1. 声明变量
var num int
var ptr *int

在这里,我们创建了一个整型指针变量 ptr 和一个普通变量 num。这两个变量最初没有初始化,因此指针 ptr 不指向任何地址。
2. 给常规变量赋值
num = 22

这会将 22 赋给变量 num。也就是说,22 存储在变量 num 的内存位置。
3. 将地址赋给指针
ptr = &num

这会将变量 num 的地址赋给指针 ptr。
4. 更改变量的值
num = 11

这会将 11 赋给变量 num。
5. 使用指针更改值
*ptr = 2

这会将指针 ptr 指向的内存位置的值更改为 2。
常见问题
当我们声明一个指针变量但未对其进行初始化时,指针的值始终为 nil。例如:
// Program to illustrate the nil pointers
package main
import "fmt"
func main() {
// declare a pointer variable
var ptr *int
fmt.Println("Value of pointer:", ptr)
}
输出
Value of pointer: <nil>
这里,指针 ptr 未初始化,因此它不指向任何地址。因此,指针的默认值始终为 nil。
我们也可以使用 new()
函数在 Go 中创建指针。例如:
// Program to create pointer using new() function
package main
import "fmt"
func main() {
// create a pointer using new()
var ptr = new(int)
*ptr = 20
fmt.Println(ptr) // 0xc000016058
fmt.Println(*ptr) // 20
}
这里,在行 var ptr = new(int)
中,变量 ptr 成为一个 int
类型的指针。
当我们将 *ptr
赋给 20 时,ptr 在内存位置的值变为 20。
在 Go 中,我们也可以不使用 *
运算符来创建指针变量。例如:
package main
import "fmt"
func main() {
var name = "John"
// create pointer without *
var ptr = &name
fmt.Println("Value of ptr:", ptr)
fmt.Println("Address of name:", &name)
}
输出
Value of ptr: 0xc0000101e0 Address of name: 0xc0000101e0
这里,我们直接将 &name
(name 的地址)赋给了 ptr
变量。
在这种情况下,该变量是一个指针变量,尽管我们没有使用 *
运算符。