Go-struct

1.关于 Golang 结构体

  • Golang 中没有“类”的概念,Golang 中的结构体和其他语言中的类有点相似。和其他面向对象语言中的类相比,Golang 中的结构体具有更高的扩展性和灵活性。
  • Golang 中的基础数据类型可以表示一些事物的基本属性,但是当我们想表达一个事物的全部或部分属性时,这时候再用单一的基本数据类型就无法满足需求了,
  • Golang 提供了一种自定义数据类型,可以封装多个基本数据类型,这种数据类型叫结构体,英文名称 struct。
  • 也就是我们可以通过 struct 来定义自己的类型了。

2.结构体定义初始化的几种方法

2.1结构体的定义

使用 type 和 struct 关键字来定义结构体,具体代码格式如下
type 类型名 struct { 
    字段名 字段类型 
    字段名 字段类型
 … 
}
/*
注意:结构体首字母可以大写也可以小写,大写表示这个结构体是公有的,
在其他的包里面 可以使用。小写表示这个结构体是私有的,只有这个包里面才能使用。
 */
type person struct {
    sex string
    // 可以写在一行
    name,city string
    age int

}

2.2六种实例化方法

package main

import "fmt"

/*
注意:结构体首字母可以大写也可以小写,大写表示这个结构体是公有的,
在其他的包里面 可以使用。小写表示这个结构体是私有的,只有这个包里面才能使用。
*/
type person struct {
    sex string
    // 可以写在一行
    name, city string
    age        int
}

func main() {
    // 1.结构体实例化(第一种方法)
    var p1 person
    p1.age = 22
    p1.name = "GJH"
    p1.city = "北京"
    p1.sex = "男"
    fmt.Println(p1)     //{男 GJH 北京 22}
    fmt.Println(p1.sex) // 男

    //2.第二种实例化
    var p2 = new(person)
    p2.sex = "男"
    p2.name = "GJH"
    fmt.Println(p2) // &{男 GJH  0} p2 是一个结构体指针

    //3.使用&对结构体进行取地址操作相当于对该结构体类型进行了一次 new 实例化操作。
    p3 := &person{}
    p3.sex = "女"
    p3.name = "LYL"
    fmt.Println(p3) //&{女 LYL  0}

    //4.结构体实例化(第四种方法) 键值对初始化
    p4 := person{
        sex: "男",
        age: 22, //注意:最后一个属性的","要加上
    }
    fmt.Println(p4) //{男   22}

    //5.结构体实例化(第五种方法) 结构体指针进行键值对初始化
    p5 := &person{
        name: "码云",
    }
    fmt.Println(p5) //&{ 码云  0}

    //6.结构体实例化(第六种方法) 使用值的列表初始化
    /*
        初始化结构体的时候可以简写,也就是初始化的时候不写键,直接写值:
        使用这种格式初始化时,需要注意:
            1.必须初始化结构体的所有字段。
            2.初始值的填充顺序必须与字段在结构体中的声明顺序一致。
            3.该方式不能和键值初始化方式混用
            4.字段数量一致
    */
    p7 := &person{
        "男",
        "马化腾",
        "北京",
        22,
    }
    fmt.Println(p7) //&{男 马化腾 北京 22}

}

3.结构体属性类型使用

package main

import "fmt"

/*

结构体的字段类型可以是:基本数据类型、也可以是切片、Map 以及结构体

如果结构体的字段类型是: 指针,slice,和map的零值都是 nil ,即还没有分配空间

如果需要使用这样的字段,需要先make,才能使用.

*/

type Person struct {
    Name  string
    Age   int
    Hobby []string
    map1  map[string]string
}

func main() {

    var p Person
    p.Name = "张三"
    p.Age = 20
    p.Hobby = make([]string, 2, 6)
    p.Hobby[0] = "写代码"
    p.Hobby[1] = "打篮球"

    p.map1 = make(map[string]string)
    p.map1["address"] = "北京"
    p.map1["phone"] = "1324325325"

    fmt.Printf("%#v\n", p)
    //main.Person{Name:"张三", Age:20, Hobby:[]string{"写代码", "打篮球", "睡觉"}, map1:map[string]string{"address":"北京", "phone":"1324325325"}}

    fmt.Printf("%v", p.Hobby) //[写代码 打篮球 睡觉]

}

4.结构体嵌套

package main

import "fmt"

type User1 struct {
    Name  string
    Age   int
    ccc   string
    User2 User2 // 这就是结构体的嵌套 获取的时候要加上结构体名字 User2.属性
    User3       // 这就是结构体的匿名嵌套 匿名嵌套 获取的属性的时候 会自己在结构体内寻找

}

type User2 struct {
    aaa string
    bbb int
    ccc string
}

type User3 struct {
    Hobby   string
    school  string
    AddTime string
    ccc     string
}

func main() {
    var u User1
    u.Name = "GJH"
    u.Age = 22
    u.ccc = "ccc"
    /*
        错误写法
        u.aaa = "asdasd"  // 如果结构体不是写的匿名嵌套 要加上结构体名字进行获取属性
    */
    // 正确写法
    u.User2.aaa = "aaa"
    u.User2.bbb = 11111
    u.User2.ccc = "ccc2"

    // 直接修改User3的AddTime
    u.school = "清华"
    u.AddTime = "2021-03-27"
    u.User3.ccc = "ccc3"
    fmt.Println(u) //    {GJH 22 ccc {aaa 11111 ccc2} { 清华 2021-03-27 ccc3}}

    /*
        注意:
            1.当访问结构体成员时会先在结构体中查找该字段,找不到再去匿名结构体中查找。
            2.当有相同属性的时候 访问要加上结构体的名字 :u.User2.ccc = "ccc2"
    */

}

5.结构体方法

/*


结构体可以描述现实生活中的任何事物,生活中的任何事物都可以当做结构体对象

我们可以把客观事物封装成结构体 :

    汽车

         汽车有属性:颜色   大小   重量  发动机   轮胎 ...

         汽车行为 也叫方法:  run  跑


    小狗

        属性:颜色     大小     品种  性别 ..

        行为:叫    、闻一闻  舔一舔  咬一咬

    电风扇

        属性: 颜色 大小  高低...

        行为:转动

    人也是一个结构体对象:

        属性: 名字  年龄 性别 ...

        行为:工作  运动 ..


*/

package main

import "fmt"

type Person struct {
    Name   string
    Age    int
    Sex    string
    height int
}

func (p Person) PrintInfo() {
    fmt.Printf("姓名:%v 年龄:%v\n", p.Name, p.Age)
}

func main() {

    var p1 = Person{
        Name: "张三",
        Age:  20,
        Sex:  "男",
    }
    p1.PrintInfo() //姓名:张三 年龄:20

    var p2 = Person{
        Name: "李四",
        Age:  30,
        Sex:  "男",
    }
    p2.PrintInfo() //姓名:李四 年龄:30

    p1.PrintInfo() //姓名:张三 年龄:20

}

6.结构体继承

package main

import "fmt"

//父亲结构体
type Animal struct {
    Name string
}

func (a Animal) run() {
    fmt.Printf("%v 在运动\n", a.Name)
}

//子结构体

type Dog struct {
    Age    int
    Animal //结构体嵌套 继承
}

func (d Dog) wang() {
    fmt.Printf("%v 在旺旺\n", d.Name)
}

func main() {
    var d = Dog{
        Age: 20,
        Animal: Animal{
            Name: "阿奇",
        },
    }
    d.run()    //阿奇 在运动
    d.wang() //阿奇 在旺旺

}

7.结构体&JSON互相转换

Golang JSON 序列化是指把结构体数据转化成 JSON 格式的字符串

Golang JSON 的反序列化是指把 JSON 数据转化成 Golang 中的结构体对象

Golang 中 的 序 列 化 和 反 序 列 化 主 要 通 过 "encoding/json" 包 中 的 json.Marshal() 和 json.Unmarshal() 方法实现

package main

import (
    "encoding/json"
    "fmt"
)

type Student struct {
    ID     int
    Gender string
    Name   string //私有属性不能被 json 包访问
    Sno    string
}

func main() {
    // 结构体转JSON
    var s1 = Student{
        ID:     1,
        Gender: "男",
        Name:   "李四",
        Sno:    "s0001",
    }

    //fmt.Printf("%#v\n", s1)
    var s, _ = json.Marshal(s1)
    jsonStr := string(s)
    fmt.Println(jsonStr) //{"ID":1,"Gender":"男","Name":"李四","Sno":"s0001"}

    // JSON 转结构体
    var jsonStr2 = `{"ID":1,"Gender":"男","Name":"李四","Sno":"s0001"}`
    //定义一个 Monster 实例
    var student Student
    err := json.Unmarshal([]byte(jsonStr2), &student)
    if err != nil {
        fmt.Printf("unmarshal err=%v\n", err)
    }
    fmt.Printf("反序列化后 student=%#v student.Name=%v \n", student, student.Name)
    //反序列化后 student=main.Student{ID:1, Gender:"男", Name:"李四", Sno:"s0001"} student.Name=李四
}

结构体Tag

结构体标签:可以指定属性转换之后的字段名(起别名)

package main

import (
    "encoding/json"
    "fmt"
)

type Student struct {
    ID     int    `json:"id"` //通过指定 tag 实现 json 序列化该字段时的 key
    Gender string `json:"gender"`
    Name   string `json:"name"`
    Sno    string `json:"sno"`
}

func main() {
    var s1 = Student{
        ID:     1,
        Gender: "男",
        Name:   "李四",
        Sno:    "s0001",
    }
    //fmt.Printf("%#v\n", s1)  //main.Student{ID:1, Gender:"男", Name:"李四", Sno:"s0001"}
    var s, _ = json.Marshal(s1)
    jsonStr := string(s)
    fmt.Println(jsonStr) //{"id":1,"gender":"男","name":"李四","sno":"s0001"}
}

 

 

 

 

posted @ 2019-11-14 23:51  GJH-  阅读(71)  评论(0)    收藏  举报