结构体所有字段在内存当中是连续的
type Point struct {
x, y int
}
type Rect struct {
left, up Point
}
func main() {
r := Rect{
left: Point{
x: 16,
y: 18,
},
up: Point{
x: 19,
y: 20,
},
}
fmt.Printf("%p,%p \n", &r.left, &r.up)
fmt.Printf("%p,%p,%p,%p", &r.left.x, &r.left.y, &r.up.x, &r.left.y)
}
0xc0000141a0,0xc0000141b0
0xc0000141a0,0xc0000141a8,0xc0000141b0,0xc0000141a8
一个int类型刚好8个字节。可以看到结构体的字段在内存当中是连续分布的,通过地址的加减来找到对应的数据。
可以看到指针的地址也是连续的,r有两个*point类型,这个两个*Point类型的本身地址也是连续的,但是他们指向的地址不一定是连续。
结构体转换
结构体是用户单独定义的类型,和其它类型进行转换时需要有完全相同的字段(字段、个数和类型)
type A struct{
Num int
}
type B struct{
Num int
}
func main(){
var a A
var b B
b=B(a)//这里正确吗?
}
字段名称,字段类型,字段个数都得一致才可以转。
tag 结构体标签 结构体序列化
结构体字段是大写的,这样是为了能够在别的包中使用。
序列化的概念就是将一个变量序列化为字符串然后再返回给客户端。这个字符串有个通用的格式就是json,别人返回字段并不希望是大写的,更加希望返回的json字段是小写的。
这个时候就可以给结构体加上tag,在tag里面可以指定小写的字段。这样不仅仅可以在其他包中访问你的字段,并且可以将你大写的字段名改为希望的字段名称。
在使用json包的Marshal方法的时候,相当于在别的包,也就是在别的包里面访问结构体变量了。如果你的结构体变量是小写的,那么根据作用域的原则,那么在json的Marshal方法里面是访问不到这些小写的变量的,无法序列化,因此只可以大写。但是大写序列化之后的结果是大写,这样就需要使用tag。文章来源:https://www.toymoban.com/news/detail-672334.html
json的Marshal函数当中使用了反射。 文章来源地址https://www.toymoban.com/news/detail-672334.html
- 字段大写就可以序列化
- tag序列化后小写的字符串通过网络返回给客户端
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string `json:"username"`
Age int `json:"age"`
phone string `json:"phone"`
}
func main() {
p := &Person{
Name: "lucas",
Age: 29,
phone: "123456",
}
//将person序列化为json格式字符串
if data, err := json.Marshal(p); err != nil {
fmt.Println(err.Error())
} else {
fmt.Println(string(data))
}
d, _ := json.Marshal(p)
var p1 Person
json.Unmarshal(d, &p1)
fmt.Printf("%#v", p1)
}
{"username":"lucas","age":29}
main.Person{Name:"lucas", Age:29, phone:""}
到了这里,关于Golang struct 结构体注意事项和使用细节的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!