Go 指针和结构体学习总结
1. 指针
变量是一种使用方便的占位符,用于引用计算机内存地址。 Go
语言的取地址符是 &
,放到一个变量前使用就会返回相应变量的内存地址。
package main
import "fmt"
func main() {
var a int = 20
fmt.Printf("变量 a 的地址: %x\n", &a)
}
输出结果如下:
变量 a 的地址: c420014078
指针的概念是:指向任何一个值的内存地址,是内存地址的编号。
重点:
- 是 go 中基本数据类型
- 代表内存地址
- 可以指向任意数据的地址
- 不同数据类型的指针需要不同的数据类型和指针符号组合来表示
**特别注意:**指针和其他类型的变量一样,需要申明和赋值后才能使用。
package main
import "fmt"
func main() {
var a int = 20 //声明变量 a
var aPointer *int //声明指针变量
aPointer = &a //将变量 a 的地址赋值给指针变量
fmt.Printf("变量 a 的地址是: %x\n", &a)
fmt.Printf("aPointer 变量储存的指针地址: %x\n", aPointer)
fmt.Printf("*aPointer 变量的值: %d\n", *aPointer) //使用指针访问值
}
输出结果如下:
变量 a 的地址是: c420014078
aPointer 变量存储的指针地址是: c420014078
aPointer 变量的值是: 20
1.1 空指针
当一个指针被定义后没有分配到任何变量时,它的值为 nil
。nil
指针也称为空指针。
nil
在概念上和其它语言的 null、None、nil、NULL
一样,都指代零值或空值。
一个指针变量通常缩写为 ptr
。
注意,指针还有以下操作:
- 指针数组(核心是数组和指针)
- 多级指针(指向指针的指针)
- 函数的指针参数
demo:
package main
import "fmt"
func swap(a, b *int) {
temp := *a//声明变量 temp 并初始化
*a = *b
*b = temp
}
func main() {
var a int = 20
var aPointer *int //声明指针变量
aPointer = &a
fmt.Printf("a 变量的地址是: %x\n", &a)
fmt.Printf("aPointer 变量存储的指针地址是: %x\n", aPointer)
fmt.Printf("aPointer 变量的值是: %d\n", *aPointer)
b := 35
bPointer := &b
fmt.Printf("a = %d, b = %d\n", a, b)
fmt.Printf("aPointer = %x, bPointer = %x\n", aPointer, bPointer)
swap(aPointer, bPointer)
fmt.Println("交换后的结果")
fmt.Printf("a = %d, b = %d\n", a, b)
fmt.Printf("aPointer = %x, bPointer = %x\n", aPointer, bPointer)
pBPtr := &bPointer
fmt.Printf("pBPtr = %x, *pBPtr = %x, **pBPtr = %d\n", pBPtr, *pBPtr, **pBPtr)
}
输出结果如下:
a 变量的地址是: c420014078
aPointer 变量存储的指针地址是: c420014078
aPointer 变量的值是: 20
a = 20, b = 35
aPointer = c420014078, bPointer = c420014088
交换后的结果
a = 35, b = 20
aPointer = c420014078, bPointer = c420014088
pBPtr = c42000c030, *pBPtr = c420014088, **pBPtr = 20
上面的 demo 中,我们可以明显的看到 a、b 的值在交换后发生了变化,但是 aPointer 和 bPointer 的值并没有发生变化。
在交换函数中,我们把 a、b 的值通过指针操作的方式直接更改了,但是 aPointer 和 bPointer 是指向了 a、b 的地址,我们并没有改变它们,所以 aPointer 和 bPointer 值没有变化。
接着我们声明并且初始化了一个二级指针 pBPtr,它的值是 bPointer 这个指针变量的地址,接着 *pBPtr
的值是 bPointer 指向的地址也就是 b 的地址,所以 **pBPtr
的值是变量 b 的值。
2. 结构体
package main
import "fmt"
type Person struct {
name string
age int
}
/*
属性访问:结构体变量名.属性名
*/
func (person Person) logPerson() {
fmt.Printf("%s, 年龄: %d\n", person.name, person.age)
}
func main() {
var aPerson Person //声明 aPerson 变量,且数据类型是结构体 Person
aPerson.name = "lisi"
aPerson.age = 22
aPerson.logPerson()
}
输出结果如下:
lisi, 年龄: 22
3. 总结
- 指针支持任意数据类型的操作,指针申明格式为:
var *name dataType
- 指针存储内存地址,&是取变量的地址,*是取指针指向内存的值
- 多级指针的层级
- 结构体可以称之为扩展数据类型或包装数据类型
- 结构体用于定义非基本数据类型
- 结构体的基本操作(属性读写、函数参数、结构体指针)
4. 参考文档
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论