什么是结构体

1.Golang中没有类的概念,也不支持类的继承等面向对象的概念
2.所以Go通过结构体的内嵌再配合接口实现比面向对更高的扩展性和灵活性

结构体定义

基本实例化

package main

import "fmt"

type person struct {
	name string
	city string
	age  int
}

func main() {
	/*
		只有当结构体实例化时,才会分配内存,也就是说必须实例化后才能使用结构体的字段
	*/
	var p1 person
	p1.name = "张三"
	p1.city = "上海"
	p1.age = 20
	fmt.Printf("p1=%v\n", p1) // p1={张三 上海 20}
	fmt.Printf("p1=%#v\n", p1) // p1=main.person{name:"张三", city:"上海", age:20}
}

new实例化

package main

import "fmt"

type person struct {
	name string
	city string
	age  int
}

func main() {
	/*
		还可以通过new关键字对结构退进行实例化,得到的是结构体的地址
	*/
	var p1 = new(person)
	p1.name = "张三" // 底层是用的指针 (*p1).name = "张三"
	p1.city = "上海"
	p1.age = 20
	fmt.Printf("p1=%#v\n", p1) //p1=&main.person{name:"张三", city:"上海", age:20}
}

键值对初始化

package main

import "fmt"

type person struct {
	name string
	city string
	age  int
}

func main() {
	p1 := person{
		name: "张三",
		city: "上海",
		age:  20,
	}
	fmt.Printf("p1=%#v\n", p1) // p1=main.person{name:"张三", city:"上海", age:20}
}

结构体方法和接收者

结构体说明

func (接收者变量 接收者类型) 方法名(参数列表) (返回参数) {函数体}

结构体方法和接收者

package main

import "fmt"

type Person struct {
	name string
	age  int
}

func (p Person) printInfo() {
	fmt.Printf("姓名:%v 年龄:%v\n", p.name, p.age)
}

func main() {
	p := Person{
		name: "小红",
		age:  20,
	}
	p.printInfo() // 姓名:小红 年龄:20
}

值类型和指针类型接收者

将接收者的值复制一份修改操作只是针对副本

2、指针类型的接收者
指针类型的接收者由一个结构体的指针组成
指针大家够知道,修改是直接修改内存中指向的地址值,所以修改的是原数据的值

package main

import "fmt"

type Person struct {
	name string
	age  int
}

//值类型接收者
func (p Person) printInfo() {
	fmt.Printf("姓名:%v 年龄:%v\n", p.name, p.age)
}

//指针类型接收者
func (p *Person) setInfo(name string, age int) {
	p.name = name
	p.age = age
}

func main() {
	p := Person{
		name: "小红",
		age:  20,
	}
	p.printInfo() // 姓名:小红 年龄:20
	p.setInfo("张三", 30)
	p.printInfo() // 姓名:张三 年龄:30
}

struct与json

  • 在写后台接口时需要提供json数据,就要用到结构图和json间的转换
  • JSON序列化是把结构体数据转化成JSON
  • JSON反序列化是把JSON数据转化成结构体对象
  • 序列化和反序列化主要通过’encoding/json’包中的json.Marshal()和json.Unmarshal()方法

struct转json字符串

package main

import (
	"encoding/json"
	"fmt"
)

type Student struct {
	ID     int
	Gender string
	name   string
	Son    string
}

func main() {
	var s1 = Student{
		ID:     1,
		Gender: "男",
		name:   "傻宝",
		Son:    "s001",
	}
	fmt.Printf("%#v\n", s1) // main.Student{ID:1, Gender:"男", name:"傻宝", Son:"s001"}
	var s, _ = json.Marshal(s1)
	jsonStr := string(s)
	fmt.Println(jsonStr) //{"ID":1,"Gender":"男","Son":"s001"}
}

json转struct

package main

import (
	"encoding/json"
	"fmt"
)

type Student struct {
	ID     int
	Gender string
	Name   string
	Son    string
}

func main() {
	var jsonStr = `{"ID":1, "Gender":"男", "Name":"傻宝", "Son":"s001"}`
	var student Student
	err := json.Unmarshal([]byte(jsonStr), &student)
	if err != nil {
		fmt.Println("unmarshal err:", err)
	}
	fmt.Printf("反序列化后 student=%#v student.Name=%v \n", student, student.Name)
	// 反序列化后 student=main.Student{ID:1, Gender:"男", Name:"傻宝", Son:"s001"} student.Name=傻宝
}

struct tag

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

Tag结构体转化Json字符串

package main

import (
	"encoding/json"
	"fmt"
)

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

func main() {
	var s1 = Student{
		ID:     1,
		Gender: "女",
		Name:   "李四",
		Son:    "s002",
	}
	fmt.Printf("%#v\n", s1) // main.Student{ID:1, Gender:"女", Name:"李四", Son:"s002"}
	var s, _ = json.Marshal(s1)
	jsoStr := string(s)
	fmt.Println(jsoStr) // main.Student{ID:1, Gender:"女", Name:"李四", Son:"s002"}
}

Json字符串转成Tag结构体

package main

import (
	"encoding/json"
	"fmt"
)

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

func main() {
	var s3 Student
	jsonStr := `{"id":1,"gender":"女","Name":"李四","Son":"s002"}`
	err := json.Unmarshal([]byte(jsonStr), &s3)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Printf("%#v\n", s3) // {"id":1,"gender":"女","Name":"李四","Son":"s002"}
}