Go语言中结构体

作者: ropon 分类: Go 发布时间: 2019-11-07 09:58
package main

import "fmt"

// MyInt type 自定义类型
// MyInt 是一种新类型 它具有int的特性
type MyInt int

// SayHi 给自定义MyMyInt添加方法
func (m MyInt) SayHi() {
	fmt.Println("Hello World!")
}

// 类型别名 Type TypeAlias = Type
// type byte = uint8
// type rune = int32

// 类型自定义与类型别名区别
// type NewInt int
// 代码中存在
// type MyInt = int

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

type person struct {
	name string
	age  int8
	addr string
}

// 定义方法
func (p person) Sleep() {
	fmt.Printf("%s非常想睡觉\n", p.name)
}

// 类似于其他面向对象语言中self或this 修改实例变量
func (p *person) Modage(newage int8) {
	p.age = newage
}

// 接收者类型是值类型 运行时会拷贝一份副本 无法修改接收者变量本身
func (p person) Modage2(newage int8) {
	p.age = newage
}

// People 结构体匿名字段
type People struct {
	string
	int8
}

// 因结构体字段名必须唯一 匿名字段同一类型只有一个

// Address 结构体嵌套
type Address struct {
	province   string
	city       string
	createtime string
}

// User 定义结构体
type User struct {
	name    string
	gender  string
	address Address
}

// Renmen 嵌套匿名结构体
// 访问结构体成员时会先在结构体中查找该字段 找不到再去匿名结构体中查找
type Renmen struct {
	name   string
	gender string
	Address
}

// Email 嵌套结构体 字段名冲突
type Email struct {
	account    string
	createtime string
}

// NiuBi 自定义结构体
type NiuBi struct {
	name   string
	gender string
	Address
	Email
}

// Animal 动物
// 结构体的“继承”
type Animal struct {
	name string
}

func (a *Animal) move() {
	fmt.Printf("%s会动\n", a.name)
}

// Dog 够
type Dog struct {
	age int8
	// 通过嵌套匿名结构体实现继承
	*Animal
}

func (d *Dog) jiao() {
	fmt.Printf("%s会汪汪汪叫\n", d.name)
}

// Xueyuan 学员结构体
type Xueyuan struct {
	ID     int
	Name   string
	Gender string
}

func main() {
	// var a NewInt
	// var b MyInt
	// fmt.Printf("type of a: %T\n", a)
	// fmt.Printf("type of b: %T\n", b)
	// type of a: main.NewInt
	// type of b: int

	// 结构体实例化
	// var 结构体实例 结构体类型 通过. 访问结构体的字段
	// var p1 person
	// p1.name = "Ropon"
	// p1.age = 20
	// p1.addr = "Chengdu"
	// fmt.Printf("p1 = %v\n", p1)
	// fmt.Printf("p1 = %#v\n", p1)

	// 匿名结构体
	// var user struct {
	// 	name string
	// 	age  int
	// }
	// user.name = "Pengge"
	// user.age = 22
	// fmt.Printf("user = %#v\n", user)

	// 创建指针类型结构体
	// var p2 = new(person)
	// fmt.Printf("%T\n", p2)
	// fmt.Printf("p2 = %#v\n", p2)
	// 指针结构类型也支持通过.访问结构体的字段
	// p2.name = "West"
	// p2.age = 28
	// p2.addr = "Beijing"
	// fmt.Printf("p2 = %#v\n", p2)
	// fmt.Println(p2.name)

	// 取结构体的地址进行实例化
	// p3 := &person{}
	// fmt.Printf("%T\n", p3)
	// fmt.Printf("p3 = %#v\n", p3)
	// p3.name = "Niubi"
	// p3.age = 30
	// p3.addr = "Shanghai"
	// fmt.Printf("p2 = %#v\n", p3)
	// fmt.Println(p3.name)

	// 结构体初始化 没有初始化结构体 其成员都是对应类型的默认值

	// 使用键值对初始化
	// p4 := person{
	// 	name: "Lisi",
	// 	age:  26,
	// 	addr: "Shenzhen",
	// }
	// fmt.Printf("p4 = %#v\n", p4)

	// 指针类型结构体也可以通过键值对初始化
	// p5 := &person{
	// 	name: "Lisi",
	// 	age:  26,
	// 	addr: "Shenzhen",
	// }
	// fmt.Printf("p5 = %#v\n", p5)
	// 初始化值时,字段名可以不写,那么没有指定值就是该类型的默认值

	// 使用值的列表初始化 必须初始化结构体所有字段 顺序必须一致 不能与键值混用
	// p6 := &person{
	// 	"Lisi",
	// 	26,
	// 	"Shenzhen",
	// }
	// fmt.Printf("p6 = %#v\n", p6)

	// 结构体内存布局 占用一块连续的内存
	// type test struct {
	// 	a int8
	// 	b int8
	// 	c int8
	// 	d int8
	// }
	// t := test{
	// 	1, 2, 3, 4,
	// }
	// fmt.Printf("t.a %p\n", &t.a)
	// fmt.Printf("t.b %p\n", &t.b)
	// fmt.Printf("t.c %p\n", &t.c)
	// fmt.Printf("t.d %p\n", &t.d)

	// 练习
	// type student struct {
	// 	name string
	// 	age int
	// }
	// m := make(map[string]*student)
	// stus := []*student{
	// 	{name: "Ropon", age: 18},
	// 	{name: "Pengge", age: 20},
	// 	{name: "Rencai", age: 22},
	// }
	// for _, stu := range stus {
	// 	// fmt.Println(stu.name)
	// 	// fmt.Printf("%P\n", stu.name)
	// 	m[stu.name] = stu
	// }
	// for k, v := range m {
	// 	fmt.Println(k, "=>", v.name)
	// 	// fmt.Println(k, "=>", (*v).name)
	// }
	// Ropon => Ropon
	// Pengge => Pengge
	// Rencai => Rencai

	// 方法
	// 定义格式
	// func (接收者变量 接收者类型) 方法名(参数列表) (返回参数) {
	// 	函数体
	// }
	// 接收者变量 一般使用接收者类型的第一个小写字母 而不是self this
	// 接收者类型 与参数类似 可以是指针类型或值类型
	// 方法名、参数列表 返回参数 与函数定义相同
	// p4 := person{
	// 	name: "Lisi",
	// 	age:  26,
	// 	addr: "Shenzhen",
	// }
	// p4.Sleep()
	// p4.Modage(28)
	// fmt.Println(p4)
	// p4.Modage2(30)
	// fmt.Println(p4)
	// 方法与函数区别: 函数不属于任何类型 方法属于特定类型
	// 什么情况该使用指针类型接收者
	// 需要修改接收者中的值
	// 接收者拷贝代价高的大对象
	// 方法接收者类型统一

	// 任意类型 添加方法
	var m1 MyInt
	m1.SayHi()
	m1 = 100
	fmt.Printf("%#v %T\n", m1, m1)
	p1 := People{
		"rencai",
		22,
	}
	fmt.Printf("%#v\n", p1)
	fmt.Println(p1.string, p1.int8)

	u1 := User{
		name:   "Pengge",
		gender: "男",
		address: Address{
			province: "Sc",
			city:     "Cd",
		},
	}
	fmt.Println(u1)
	fmt.Printf("%#v\n", u1)

	var u2 Renmen
	u2.name = "Ropon"
	u2.gender = "男"
	u2.Address.province = "Sc"
	u2.Address.city = "Cd"
	fmt.Printf("%#v\n", u2)

	var u3 NiuBi
	u3.name = "Niubi666"
	u3.gender = "Man"
	// u3.createtime = "2019"
	u3.Address.createtime = "2020"
	u3.Email.createtime = "2020"
	fmt.Printf("%#v\n", u3)

	d1 := &Dog{
		age: 4,
		Animal: &Animal{
			name: "erduo",
		},
	}
	d1.jiao()
	d1.move()

	// 结构体字段可见性
	// 结构体字段大写表示公有 小写表示私有(仅在定义当前结构体中可访问) 通过包导入无法访问

	x := &Xueyuan{
		1,
		"Ropon",
		"男",
	}
	fmt.Println(x)
}

// 结构体 <==> JSON
package main

import (
	"encoding/json"
	"fmt"
)

// Student 班级
type Student struct {
	ID     int
	Gender string
	Name   string
}

// Class 班级
type Class struct {
	Title    string
	Students []*Student
}

// Student2 结构体
// 结构体标签 Tag
// 语法
// `key1:"value1" key2:"value2"`

//Student2 测试学生信息
type Student2 struct {
	ID     int `json:"id"`
	Gender string
	Name   string
}

func main() {
	c := &Class{
		Title:    "101",
		Students: make([]*Student, 0, 200),
	}
	for i := 0; i < 5; i++ {
		stu := &Student{
			Name:   fmt.Sprintf("stu%02d", i),
			Gender: "男",
			ID:     i,
		}
		c.Students = append(c.Students, stu)
	}

	//JSON序列化: 结构体 --> JSON格式的字符串
	//data, err := json.Marshal(c)
	//if err != nil {
	//	fmt.Println("json marshal failed")
	//	return
	//}
	//fmt.Printf("json:%s\n", data)

	//JSON反序列化:JSON格式的字符串-->结构体
	jsonstr := `
		{"Title":"101","Students":[{"ID":0,"Gender":"男","Name":"stu00"},
		{"ID":1,"Gender":"男","Name":"stu01"},{"ID":2,"Gender":"男","Name":"stu02"},
		{"ID":3,"Gender":"男","Name":"stu03"},{"ID":4,"Gender":"男","Name":"stu04"}]}`

	c1 := &Class{}
	err := json.Unmarshal([]byte(jsonstr), c1)
	if err != nil {
		fmt.Println("json unmarshal failed!")
		return
	}
	//fmt.Printf("%#v\n", c1.Students)
	for index, value := range c1.Students {
		fmt.Println(index, value.Name, value.ID)
	}

	//s1 := Student2{
	//	1,
	//	"男",
	//	"人才",
	//}
	//data, err := json.Marshal(s1)
	//if err != nil {
	//	fmt.Println("json marshal failed!")
	//	return
	//}
	//fmt.Printf("json str: %s\n", data)

}

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!