Golang学习笔记_08------For循环
Golang学习笔记_09------if条件判断
Golang学习笔记_10------Switch
文章目录
指针
在Go语言中,指针是一种非常基本且重要的数据类型,它允许你直接访问和操作内存地址。指针的使用在C和C++等语言中非常普遍,但Go语言在提供指针功能的同时,也尽量简化了其复杂性,使得指针在Go中相对安全且易于使用。
1. 定义
指针是一个存储了内存地址的变量。在Go中,你可以通过 *Type
来声明一个指针,其中 Type
是指针指向的变量的类型。例如,*int
是一个指向 int
类型变量的指针。
go
var p *int
2. 初始化
你可以将变量的地址赋值给指针。使用 &
操作符来获取变量的内存地址。
go
var a int = 42
var p *int &a
3. 解引用指针
解引用(或称取消引用)指针意味着访问指针所指向的内存位置的值。在Go中,这是通过前置星号*
完成的。
go
fmt.Println(*p) // 打印 p 指向的值,即 x 的值
*p = 21 // 修改 p 指向的值,即修改 x 的值
4. 指针的传递
在函数调用时,如果你希望函数能够修改调用者的变量,你可以将变量的指针传递给函数。
go
func modifyValue(p *int) {
*p = 100
}
测试方法
go
func Test_modifyValue(t *testing.T) {
num := 40
type args struct {
p *int
}
tests := []struct {
name string
args args
}{
{
name: "init value = 1",
args: args{&num},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
modifyValue(tt.args.p)
fmt.Println("modify value = ", num)
})
}
}
输出结果
go
=== RUN Test_modifyValue
=== RUN Test_modifyValue/init_value_=_1
modify value = 100
--- PASS: Test_modifyValue (0.00s)
--- PASS: Test_modifyValue/init_value_=_1 (0.00s)
PASS
5. 指针的零值
未初始化的指针的默认值是 nil
。尝试解引用一个 nil
指针会导致运行时错误(panic)。
go
var p *int
fmt.Println(*p)
// 这将导致运行时错误: invalid memory address or nil pointer dereference
6. 指针的比较
go
var a int = 42
var b int = 42
var p1 *int = &a
var p2 *int = &b
var p3 *int = &a
fmt.Println(p1 == p2) // 输出: false
fmt.Println(p1 == p3) // 输出: true
测试方法
go
func Test_comparePoint(t *testing.T) {
comparePoint()
}
输出结果
=== RUN Test_comparePoint
false
true
--- PASS: Test_comparePoint (0.00s)
PASS
7. 其他(可选)
指针在数组、切面和结构体中会有重要作用。
go
// 指针数组
var ptrArray []*int
ptrArray = append(ptrArray, &a, &b)
fmt.Println(*ptrArray[0], *ptrArray[1]) // 输出: 42 42(假设a和b的初始值都是42)
// 指针切片
var ptrSlice []*int
ptrSlice = make([]*int, 2)
ptrSlice[0] = &a
ptrSlice[1] = &b
fmt.Println(*ptrSlice[0], *ptrSlice[1]) // 输出: 42 42(假设a和b的初始值都是42)
type Rectangle struct {
Width, Height int
}
func (r *Rectangle) Area() int {
return r.Width * r.Height
}
func (r *Rectangle) SetWidth(width int) {
r.Width = width
}
func main() {
rect := Rectangle{Width: 10, Height: 5}
fmt.Println(rect.Area()) // 输出: 50
rect.SetWidth(20)
fmt.Println(rect.Area()) // 输出: 100
}
源码
go
// point_demo.go 文件
package point_demo
import "fmt"
func modifyValue(p *int) {
*p = 100
}
func comparePoint() {
var a int = 42
var b int = 42
var p1 *int = &a
var p2 *int = &b
var p3 *int = &a
fmt.Println(p1 == p2) // 输出: false
fmt.Println(p1 == p3) // 输出: true
}
go
// point_demo_test.go 文件
package point_demo
import (
"fmt"
"testing"
)
func Test_modifyValue(t *testing.T) {
num := 40
type args struct {
p *int
}
tests := []struct {
name string
args args
}{
{
name: "init value = 1",
args: args{&num},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
modifyValue(tt.args.p)
fmt.Println("modify value = ", num)
})
}
}
func Test_comparePoint(t *testing.T) {
comparePoint()
}