type Person struct {
Name string
Age int
}
var person Person = Person{"Alice", 28}
var personPointer *Person = &person
fmt.Println(person) // 打印结构体值:{Alice 28}
fmt.Println(personPointer) // 打印结构体的内存地址
2.2 如何获取一个指针值
要获取一个变量的指针值,可以使用&操作符。
示例:
var fruit string = "apple"
pointerToFruit := &fruit
fmt.Println(fruit) // 打印原始值:apple
fmt.Println(pointerToFruit) // 打印fruit的内存地址
2.3 指针(地址)解引用
要获取指针指向的原始值,我们使用*操作符进行解引用。这允许我们间接地访问和修改指针指向的值。
示例:
var number int = 100
pointerToNumber := &number
fmt.Println(*pointerToNumber) // 通过解引用获取原始值:100
// 修改指针指向的值
*pointerToNumber = 200
fmt.Println(number) // 原始变量值被修改为:200
3. 深入理解指针
3.1 我们为什么需要指针?
指针在编程中是一个重要的工具,特别是在需要高性能、灵活性或者对内存使用有严格要求的场景中。
3.1.1 提高程序性能
指针可以减少数据复制的需要,从而提高程序的执行速度。
示例:
考虑一个场景,我们需要交换两个大的数据结构的值。
type LargeStruct struct {
Data [1000]int
}
func swapWithoutPointer(a, b LargeStruct) {
a, b = b, a
}
func swapWithPointer(a, b *LargeStruct) {
*a, *b = *b, *a
}
var x, y LargeStruct
// 使用指针交换
swapWithPointer(&x, &y)
在上面的例子中,使用指针的方法可以避免复制两次大的数据结构,从而更为高效。
3.1.2 动态数据结构
很多动态数据结构(如链表、树、图)都依赖于指针来实现。
示例:
type Node struct {
Value int
Next *Node
}
// 创建链表
first := Node{Value: 1}
second := Node{Value: 2}
third := Node{Value: 3}
first.Next = &second
second.Next = &third
fmt.Println(first.Value) // 1
fmt.Println(first.Next.Value) // 2