Go语言 带你了解结构体及其注意事项

结构体

package main

import "fmt"
import "encoding/json"

/*
结构体定义方式
type struct_name struct{
	变量名 type
}
结构体特征:
1.当字段或者结构体以大写字母开头则表示其为public,引用类型强制为public
2.在创建一个结构体变量后,如果没有给字段赋值,都对应一个零值,引用类型的零值为nil,即没有分配空间,所以当使用这样的字段所以先make才能使用 ,指针则为new
3.结构体是值类型
4.不同结构体变量的字段是独立,互不影响
结构体注意事项和细节:
1.结构体所有字段在内存中是连续的
2.结构体是用户单独定义的类型,和其他类型进行转换是需要有完全相同的字段(名字,个数和类型)
3.	结构体进行type重新定义(相当于取别名),Golang认为是新的数据类型,但是相互间可以强转
4.	struct的每个字段上,可以写上一个tag,该tag可以通过反射机制获取,常见的使用场景就是序列化和反序列化
*/
//定义一个Cat类型的结构体,字段有:名字,年龄,颜色
type Cat struct {
	Name  string `json:"name"`
	Age   int	`json:"age"`
	Color string	`json:"color"`
}
//定义结构体中的方法 func (变量 type) 方法(参数列表)(返回列表)
//注意cat *Cat是引用传递
func (cat *Cat)eat(food string){
	//cat.Name等价于(*cat).Name
	fmt.Printf("%s喜欢吃%s",cat.Name,food)
	cat.Name="小陈"
}
func main() {
	//创建结构体实例四种方式
	//第一种 var 变量名 struct_name
	var cat1 Cat
	cat1.Name = "小白"
	cat1.Age = 3
	cat1.Color = "白色"
	//第二种 变量名:=struct_name{}
	cat2 := Cat{"小黑", 4, "黑色"}
	//第三种 var 变量名 *struct_name =new (struct_name)
	var cat3 *Cat = new(Cat)
	(*cat3).Name = "小绿"
	(*cat3).Age = 5
	(*cat3).Color = "绿色"
	//第四种 var 变量名 *struct_name =&struct_name{}
	var cat4 *Cat = &Cat{"小蓝", 6, "蓝色"}
	fmt.Println(cat1)  //{小白 3 白色}
	fmt.Println(cat2)  //{小黑 4 黑色}
	fmt.Println(*cat3) //{小绿 5 绿色}
	fmt.Println(*cat4) //{小蓝 6 蓝色}
	//struct的每个字段上,可以写上一个tag,该tag可以通过反射机制获取,常见的使用场景就是序列化和反序列化
	jsonStr,err :=json.Marshal(cat1)
	if err !=nil{
		fmt.Println("json 解析错误",err)
	}
	fmt.Println(string(jsonStr)) //{"name":"小白","age":3,"color":"白色"}
	//cat1.eat("鱼")等价于(&cat1).eat("鱼")
	cat1.eat("鱼") //小白喜欢吃鱼
	fmt.Println(cat1.Name) //小陈
}

结构体在内存分布

在这里插入图片描述

结构体特征:

  1. 当字段或者结构体以大写字母开头则表示其为public,引用类型强制为public
  2. 在创建一个结构体变量后,如果没有给字段赋值,都对应一个零值,引用类型的零值为nil,即没有分配空间,所以当使用这样的字段所以先make才能使用,指针则为new
  3. 结构体是值类型
  4. 不同结构体变量的字段是独立,互不影响

结构体注意事项和细节

  • 结构体所有字段在内存中是连续的 在这里插入图片描述

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

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

  • struct的每个字段上,可以写上一个tag,该tag可以通过反射机制获取,常见的使用场景就是序列化和反序列化
    序列化使用场景:
    在这里插入图片描述

方法注意事项和细节讨论

  • 结构体类型是值类型,在方法调用中,遵守值类型的传递机制,是值拷贝传递方式
  • 如果程序员希望在方法中,修改结构体变量的值,可以通过结构体指针的方式来处理
  • Golang中方法作用在指定的数据类型上的(即:和指定的数据类型绑定),因此自定义类型,都可以有方法,而不仅仅是struct,比如int,flaot32都可以
  • 方法的访问范围控制的规则,和函数一样.方法名首字母小写,只能在本包访问,方法首字母大写开头在本包和其他包访问
  • 如果一个类型实现String()这个方法,那么fmt.Println默认会调用这个变量的String()进行输出

方法和函数的区别

  • 调用方式不一样
    函数的调用方式: 函数名(实参列表)
    方法的调用方式: 变量.方法名(实参列表)
  • 对于普通函数,接收者为 值类型时,不能将指针类型的数据直接传递,反之亦然
  • 对于方法,接收者为值类型时,可以直接用指针类型的变量调用方法,反过来同样也可以
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值