Chapter010 golang中struct结构体

上一章:Chapter009 golang中map
下一章:Chapter011 golang中方法

一、快速入门

1、声明结构体

type 结构体名称 struct{
	field1 type
	field2 type
}

例如

type Person struct {
	Name string
	Age int
	Scores [5]float64
	ptr *int
	slice []int
	map1 map[string]string
}

2、创建结构体变量和访问结构体
(1)

var person Person

(2)

var person Person = {“mary”,20}

(3)

var p3 *Person = new(Person) 
//此时p3是一个指针,因此标准的给字段赋值方式如下:
(*p3).Name = "smith"
(*p3).Age = 30
//以上写法等价于(go设计时,在底层会对这种写法处理,加上取值运算)
p3.Name = "smith"
p3.Age = 30

(4)

var person *Person = &Person{}
(*person).Name = "scott"
(*person).Age = 88

3、如果结构体名称首字母大写,那么该结构体类型可以在其他包使用
如果字段(filed、属性)首字母大写,那么可以在其他包引用

4、字段(属性)一般是基本数据类型、数组,也可以是引用类型
如果结构体的字段类型是: 指针、slice、和map 的零值都是nil,即还没有分配空间,如果需要使用slice,map,就要先 make 再使用

package main

import (
	"fmt"
	_ "fmt"
)

type Person struct {
	Name string
	Age int
	Scores [5]float64
	ptr *int
	slice []int
	map1 map[string]string
}

func main()  {
	//定义结构体
	var p1  Person
	fmt.Print(p1,"\n")
	//slice
	p1.slice = make([]int,10)
	p1.slice[0]=100
	//map
	p1.map1 = make(map[string]string)
	p1.map1["key1"] = "tom"
	fmt.Print(p1,"\n")

}

在这里插入图片描述
5、不同结构体的字段是独立的,互不影响,修改一个不会影响另外一个
6、养猫问题

package main

import (
	"fmt"
	_ "fmt"
)

type Cat struct {
	Name string
	Age string
	Color string
}

func main()  {
	var cat1 Cat
	fmt.Print(cat1,"\n") //结构体是值类型,声明即创建
	cat1.Name = "小黑"
	cat1.Age = "10"
	cat1.Color = "black"
	fmt.Print(cat1,"\n")
}

在这里插入图片描述

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

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

三、结构体在内存中的布局

1、结构体变量是值类型
2、内存图在这里插入图片描述

四、结构体注意事项和细节

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

package main

import "fmt"

type Point struct {
	x int
	y int
}

type Rect struct {
	leftUp, rightup Point
}

func main()  {
	r1 := Rect{Point{1,2},Point{3,4},}
	fmt.Printf("r1.letf.x 地址 %p,\nr1.letf.y 地址 %p,\nr1.right.x 地址 %p,\nr1.right.y 地址 %p\n",&r1.leftUp.x,
		&r1.leftUp.y, &r1.rightup.x,&r1.rightup.y)
}

在这里插入图片描述
2、指针类型时,r2 两个Point类型,这两个Point类型的本身地址连续,但是指向地址一般不连续

package main

import "fmt"

type Point struct {
	x int
	y int
}

type Rect2 struct {
	leftUp, rightup *Point
}


func main()  {
	//指针类型时
	//r2 两个*Point类型,这两个*Point类型的本身地址连续,但是指向地址一般不连续
	r2 :=Rect2{&Point{1,2},&Point{3,4}}
	fmt.Printf("本身地址 r2.letf地址 %p,r2.right地址 %p\n",&r2.leftUp,&r2.rightup)
	fmt.Printf("指向地址 r2.letf地址 %p,r2.right地址 %p",r2.leftUp,r2.rightup)
}

在这里插入图片描述
3、结构体是用户自己单独定义的类型,和其他类型进行转化是需要有完全相同的字段名(名字、个数和类型)即强制转换

type A truct{
	Name int
}
type B truct{
	Name int
}
func main(){
	var a A
	var b B
	b = A(b)
}

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

package main

import "fmt"
import "encoding/json"

type Monster struct {
	Name string `json:"name"`
	Age int	`json:"age"`
	Skill string `json:"skill"`
}
func main()  {
	//序列化 tag
	monster :=Monster{"牛魔王",100,"芭蕉扇"}
	jsonmonster ,err:=json.Marshal(monster)
	if err != nil{
		fmt.Print("错误")
	}else {
		fmt.Print(string(jsonmonster))
	}
}

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杰西啊杰西

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值