go 结构体使用注意事项和细节

一 结构体的所有字段在内存中是连续的

1 代码

package main

import "fmt"

// 结构体
type Point struct {
   x int
   y int
}

// 结构体
type Rect struct {
   leftUp, rightDown Point
}

// 结构体
type Rect2 struct {
   leftUp, rightDown *Point
}

func main() {
   r1 := Rect{Point{1, 2}, Point{3, 4}}
   // r1 有4个int,在内存中是连续分布的
   // 打印地址
   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)
   // r2 有2个 *Point 类型,这两个 *Point 类型的本身地址也是连续的,但是他们指向的地址不一定连续
   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.leftUp, r2.rightDown)
}

2 测试

r1.leftUp.x 地址=0xc0420500a0 r1.leftUp.y 地址=0xc0420500a8 r1.rightDown.x 地址=0xc0420500b0 r1.rightDown.y 地址=0xc0420500b8
r2.leftUp 本身地址=0xc0420461b0 r2.rightDown 本身地址=0xc0420461b8
r2.leftUp 指向地址=0xc042052090 r2.rightDown 指向地址=0xc0420520a0

3 内存分布

二 结构体是用户单独定义的类型,和其它类型进行转换时需要有完全相同的字段(名字、个数和类型)

1 代码

package main

import "fmt"

type A struct {
   Num int
}
type B struct {
   Num int
}

func main() {
   var a A
   var b B
   a = A(b) // 可以转换,但是有要求,就是结构体的的字段要完全一样,包括:名字、个数和类型。
   fmt.Println(a, b)
}

2 测试

{0} {0}

三 结构体进行 type 重新定义(相当于取别名),Golang 认为是新的数据类型,但是相互间可以强转

四 struct 的每个字段上,可以写上一个 tag, 该 tag 可以通过反射机制获取,常见的使用场景就是序列化和反序列化

1 序列化的使用场景

2 代码

package main

import (
   "encoding/json"
   "fmt"
)

type Monster struct {
   Name  string `json:"name"` // `json:"name"` 就是 struct tag
   Age   int    `json:"age"`
   Skill string `json:"skill"`
}

func main() {
   // 1 创建一个 Monster 变量
   monster := Monster{"牛魔王", 500, "芭蕉扇~"}
   // 2 将 monster 变量序列化为 json 格式字串
   // json.Marshal 函数中使用反射
   jsonStr, err := json.Marshal(monster)
   if err != nil {
      fmt.Println("json 处理错误 ", err)
   }
   fmt.Println("jsonStr", string(jsonStr))
}

3 测试

jsonStr {"name":"牛魔王","age":500,"skill":"芭蕉扇~"}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值