Go语言学习之结构体

结构体简介

介绍:

Go语言中的基础数据类型可以表示一些事务的基本属性,但是我们想表达一个事务的全部或部分属性时(比如一个人,她的姓名、年龄、爱好等属性),就无法满足需求了,Go语言为我们提供了一种自定义数据类型,可以封装多个基本数据类型,叫结构体,也就是struct

结构体相当于python里给类传的参数,python写法:self.name = name,self.age=age.

结构体

一、结构体定义

使用type和struct来定义结构体

type 结构体名称 struct {
   字段名 字段类型
   字段名 字段类型
}

其中

1.结构体名称: 就是自定义结构体的名称
2.字段名: 表示结构体的字段名,结构体字段必须唯一
3.字段类型: 表示结构体的字段类型,例如 string  int等

举个例子,我们定义一个名称为 Person的结构体

type Person struct {
    name string
    city string
    age int
}

同样的字段类型 还可以写在一行里

type Person struct {
    name , city string
    age int
}

这样我们就拥有Person的自定义类型,它有name,city,age三个字段,分别表示姓名、城市、年龄,这样我们使用Person这个结构体就能很方便的在程序中存储人的信息了

二、结构体实例化

//定义结构体
type Person struct {
    name , city string
    age int
}

func main(){
    var p1  Person   //实例化结构体
    p1.name = "张三"  //通过p1访问结构体的字段并赋值,例如01.name = "张三"
    p1.city = "北京"
    p1.age  = 18
    fmt.Println(p1)
}

结果:
{张三 北京 18}

三、匿名结构体

在定义一些临时数据结构等场景下还可以使用匿名结构体

func main(){
       //定义匿名结构体
    var User struct {
        Name string
        Age int
    }
        //实例化匿名结构体    
    User.Name = "李四"
    User.Age = 18
    fmt.Println(User)
}


结果 :
{李四 18}

四、对结构体指针 进行实例化

可以取结构体的指针地址进行实例化,那么p1就是一个 带指针地址的变量

type Person struct {
    name , city string
    age int
}
func main(){
    p1  := &Person{}   //取Person的内存地址进行实例化
    p1.name = "王五"   //跟平常的实例化没有区别,很方便
    p1.city = "上海"
    p1.age = 19
    fmt.Println(p1)
    fmt.Printf("类型为: %T",p1)  //打印p1的类型
}
----------------------------结果---------------------------- 结果:
&{王五 上海 19} 类型为: *main.Person //代表p1是一个带指针地址的变量

五、使用值得列表进行实例化

实例化结构体得时候可以简写,也就是说实例化得时候可以不写Key,只写Value

type Person struct {
    name , city string
    age int
}
func main(){
    p1  := &Person{
        "张三",
        "北京",
        20,
    }

    fmt.Println(p1)
    fmt.Printf("类型为: %T",p1)
}

结果:
--------------------------------结果------------------------
&{张三 北京 20}
类型为: *main.Person

这么实例化得时候 需要注意:

1.必须实例化结构体得所有字段

2.实例化得顺序必须跟结构体定义得顺序一样

3.该方式不能和平常得 Key/Value实例化 混用

六、先定义一个结构体, 然后在函数里 实例化 这个结构体,并返回指针类型的结构体(有的文章称之为 构造函数)

//定义一个结构体
type person struct {
    name string
    city string
    age int8
}

//在函数里实例化这个结构体,*person代表返回值必须时指针类型,所以必须return &person取出结构体的指针地址进行返回
func newPerson(name, city string, age int8) *person {
    return &person{       //实例化person这个结构体
        name: name,       //结构体的name字段等于函数传进来的name字段
        city: city,       //结构体的city字段等于函数传进来的city字段
        age:  age,        //结构体的age字段等于函数传进来的age字段
    }
}


func main() {
    p1  := newPerson("张三", "北京", 18)  //初始化函数,进行传参
    fmt.Println(p1)

}

---------------------结果---------------------------
&{张三 北京 18}

七、嵌套结构体

一个结构体可以嵌套 另一个结构体或结构体指针

结果:

{张三 19 {河北 唐山}}

八、匿名嵌套结构体

type User struct {
    Name string
    Age int8
    Address //匿名结构体
}
//地址结构体
type  Address struct {
    Province string
    City string
}


func main() {
    var user2  User
    user2.Name = "李四"
    user2.Age = 20
    user2.Address.Province = "河北"
    user2.Address.City = "唐山"
    fmt.Println(user2)
}

结果:

{李四 20 {河北 唐山}}

九、结构体标签(tag)

Tag是结构体的元信息,可以在运行的时候通过反射的机制读取出来

例如我们为Student结构体的每个字段定义json序列化时使用的tag

type Student struct {
    ID int  `json:"id"`  //通过指定tag实现json序列化该字段时的key,json序列化之后,ID字段就变成id了,就是这个作用
    Gender string `json:"xingbie"`
    name string
}


func main() {
    s1 := Student{
        ID:     1,
        Gender: "",
        name:   "张三",
    }
    data, err := json.Marshal(s1)
    if err != nil {
        fmt.Println("json marshal failed!")
        return
    }
    fmt.Printf("json str:%s
", data)
}
-------------------结果-----------------------------------
json str:{"id":1,"xingbie":""}
//id就是结构体里ID的tag,xingbie是结构体里Gender的tag,所以作用就是 结构体被序列化之后,key的别名
原文地址:https://www.cnblogs.com/chadiandianwenrou/p/13810523.html