34-Golang中的结构体!!!

文章详细介绍了Golang中的结构体,包括结构体和结构体变量的区别,内存布局,声明结构体字段的注意事项,以及创建结构体实例的四种方式。还讨论了结构体的内存分配机制,结构体间的转换,以及结构体字段上的tag在序列化中的应用。
摘要由CSDN通过智能技术生成

结构体和结构体变量(实例)的区别和联系

  • 1.结构体是自定义的数据类型,代表一类事物
  • 2.结构体变量(实例)是具体的,实际的,代表一个具体变量

结构体变量(实例)在内存中的布局

在这里插入图片描述

如何声明结构体

type 结构体名称 struct{

​ field1 type

​ field2 type

}

字段/属性注意事项和细节说明

  • 1.字段声明语法同变量
  • 2.字段的类型可以为:基本类型,数组或引用类型
  • 3.在创建一个结构体变量后,如果没有给字段赋值,都对应一个零值(默认值),指针、slice和map的零值都是nil,即还没有分配空间
  • 4.不同结构体变量的字段是独立,互不影响,一个结构体变量字段的更改,不影响另外一个
package main
import (
	"fmt"
)

//不影响另外一个,结构体是值类型
type Monster struct {
	Name string
	Age int
}
func main() {
	var monster1 Monster
	monster1.Name = "牛魔王"
	monster1.Age = 500

	monster2 := monster1  //结构体是值类型,默认为值拷贝
	monster2.Name = "青牛精"

	fmt.Println("monster1=", monster1)
	fmt.Println("monster2=", monster2)
}

//monster1= {牛魔王 500}
//monster2= {青牛精 500}



在这里插入图片描述

创建结构体实例的四种方式

1.方式一—直接声明:var person Person

2.方式二—{}:var person Person = Person{}

3.方式三—&:var perosn *Person = new(Person)

4.方式四—{}:var person *Person = &Person{}

package main
import (
	"fmt"
)

//不影响另外一个,结构体是值类型
type Person struct {
	Name string
	Age int
}
func main() {
	//方式2
	p2 := Person{}
	p2.Name = "tom"
	p2.Age = 19
	fmt.Println(p2)

	//方式3
	var p3 *Person = new(Person)
	//底层会对p3.Name = "smith"进行处理
	//会给p3加上取值运算 (*p).Name = "Smith"
	(*p3).Name = "smith"
	p3.Name = "john"
	p3.Age = 20
	fmt.Println(*p3)

	//方法四
	var person *Person = &Person{}
	//底层会对person.Name = "scott"进行处理,会加上(*person)
	//
	(*person).Name = "scott"
	person.Name = "ddd"
	(*person).Age = 44
	fmt.Println(*person)

}

/*
{tom 19}
{john 20}
{ddd 44}
*/


说明:

- 1.第三种和第四种方式返回的是结构体指针
- 2.结构体指针访问字段的标准方式应该是:( *结构体指针).字段名,比如( *person).Name = "tom"
- 3.但是go做了一个简化,也支持结构体指针.字段名,比如person.Name = "tom"go编译器底层对person.Name做了转化(*Person).Name

## 结构体内存分配机制

变量总是在内存中的,那么结构体变量在内存中就近是怎样存在的?

在这里插入图片描述

结构体使用细节

1.结构体的所有字段在内存中时连续的

在这里插入图片描述
2.结构体是用户单独定义的类型,和其他类型转换时需要有完全相同的字段(名字,个数和类型)

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)
}

//{0} {0}



3.结构体进行type重新定义(相当于取别名),Golang认为是新的数据类型,但是相互间可以强转
在这里插入图片描述

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

在这里插入图片描述
序列化使用场景:

在这里插入图片描述

package main
import (
	"fmt"
	"encoding/json"
)

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

func main(){
	//创建一个MOnster变量
	monster := Monster{"kunkun", 27, "sing~"}
	//将monster变量序列化为json格式字符串
	jsonStr , err := json.Marshal(monster)
	if err != nil {
		fmt.Println("json c=处理错误", err)
	}
	fmt.Println("jsonStr", string(jsonStr))
}


//jsonStr {"name":"kunkun","age":27,"string":"sing~"}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值