开发者学堂课程【Go 语言核心编程 - 面向对象、文件、单元测试、反射、TCP 编程:结构体使用细节(1)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/626/detail/9673
结构体使用细节(1)
结构体的注意事项和使用细节1
1.结构体的所有字段在内存中是连续分布的
若结构里面有五个字段,这五个字段在内存里面的地址是连续分布的,连续分布的好处是可以通过地址的加减来快速获取某个字段的值,同时这种分布形式,也利于数据的查找。
举例一:
新建文件夹,命名为structdetails,新建一个文件main.go,输入共用代码:package main
import "fmt"
func main() {
为了看清效果,需要首先定义两个结构体。第一个结构体叫做point,该结构体有两个字段,一个字段是x,另一个字段是y,均为int类型,其代码为:
type Point struct {
x int
y int
第二个结构体叫做Rect,这个结构体由矩形的左上角(left up)和右下角(right down)的点共同构成,为Rect创建一个结构体,输入以下代码:
type Rect struct {
leftUp, rightDown Point
}
func main() {
r1:= Rect{Point{1,2},Point{3,4}}
如何证明他们是连续分布的呢?只有一个办法,就是打印,通过打印出他们的地址,观察他们的分布是不是连续的。输入fmt.Printf("r1.leftup.x 地址=%p r1.leftup.y 地址=%p r1.rightDown.x地址=%p r1.rightDown.y地址=%p \n",&r1.leftup.x, &r1.leftup.y, &r1.rightDown.x, &r1.rightDown.y)
进行调用,可以看到代码过于长,输入,进行换行。进入控制台,输入cd.chapter10,cd到structdetails,run.main.go完成运行,发现各个字符之间的地址刚好相差八个字节。
打印r1中4个int的地址,发现其在内存中是连续分布的
核心代码:
package main
import "fmt"
type Point struct {
x int
y int
}
type Rect struct {
leftUp, rightDown Point
}
func main() {
r1:= Rect{Point{1,2},Point{3,4}}
fmt.Printf("r1.leftup.x 地址=%p r1.leftup.y 地址=%p r1.rightDown.x地址=%p r1.rightDown.y地址=%p \n",&r1.leftup.x, &r1.leftup.y, &r1.rightDown.x, &r1.rightDown.y)
}
内存图:
内存分析图
在内存里面有一个r1变量,它直接指向了结构体,结构体有四个字段,第一个点(x点)的地址是Oxc042008340,第二个点的地址就是在第一个点地址的基础上加了八个字节,之所以加了八个字节是因为其数据类型是int型的,同样的道理,第三个点的地址又在第二个点的基础上加八个字节,即Oxc042008350,第四个点的位置又加了八个字节,表示结构体里面字段的数据是连续分布的,连续分布可以通过地址的加减快速获取某个字段的值。
举例二
如果rect里存放的不是具体的值,而是指针,那指针里面的内容就不一定是连续的。输入以下代码:
r2 := Rect2{&Point{10,20),&Point{30,40}}
fmt.Printf("r2.leftup本身地址=%p r2.rightDown本身地址=%p \n",
&r2.leftup, &r2.rightDown)
fmt.Printf("r2.leftup 指向地址=%p r2.rightDown 指向地址=p \n",
r2.1eftup,r2.rightDown)
}
创建一个结构体rect2,里面有左上角和右下角两个点,r2中存放的是指针,指针的内容是一个地址,而指针本身也有地址啊?r2中有两个*point,这两个*point的指针类型本身的地址是连续的,但是他们指向的地址不一定是连续的,是否连续要看系统在运行时是如何分配的。
内存图
内存分析图