From 6e253612ea6de46903457cd77ef1e8fe5887c060 Mon Sep 17 00:00:00 2001 From: ZGGSONG Date: Sun, 13 Mar 2022 18:36:55 +0800 Subject: [PATCH] add struct --- LeetCode/Ex.2/main.go | 23 +++++++++++++++ Point/main.go | 40 ++++++++++++++++++++++++++ Struct/exerices.go | 24 ++++++++++++++++ Struct/exerices2.go | 64 +++++++++++++++++++++++++++++++++++++++++ Struct/json.go | 51 ++++++++++++++++++++++++++++++++ Struct/main.go | 20 +++++++++++++ Struct/methord.go | 41 ++++++++++++++++++++++++++ Struct/struct1.go | 50 ++++++++++++++++++++++++++++++++ Struct/struct2.go | 36 +++++++++++++++++++++++ Struct/structEx.go | 25 ++++++++++++++++ Struct/structExtends.go | 33 +++++++++++++++++++++ Struct/structTag.go | 33 +++++++++++++++++++++ 12 files changed, 440 insertions(+) create mode 100644 LeetCode/Ex.2/main.go create mode 100644 Point/main.go create mode 100644 Struct/exerices.go create mode 100644 Struct/exerices2.go create mode 100644 Struct/json.go create mode 100644 Struct/main.go create mode 100644 Struct/methord.go create mode 100644 Struct/struct1.go create mode 100644 Struct/struct2.go create mode 100644 Struct/structEx.go create mode 100644 Struct/structExtends.go create mode 100644 Struct/structTag.go diff --git a/LeetCode/Ex.2/main.go b/LeetCode/Ex.2/main.go new file mode 100644 index 0000000..c268973 --- /dev/null +++ b/LeetCode/Ex.2/main.go @@ -0,0 +1,23 @@ +package main + +/** +给你两个非空 的链表,表示两个非负的整数。 +它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。 +请你将两个数相加,并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外,这两个数都不会以 0开头。 +*/ +func main() { + +} + +//type ListNode + +/** + * Definition for singly-linked list. + * type ListNode struct { + * Val int + * Next *ListNode + * } + */ +//func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode { +// return nil +//} diff --git a/Point/main.go b/Point/main.go new file mode 100644 index 0000000..766cd7c --- /dev/null +++ b/Point/main.go @@ -0,0 +1,40 @@ +package main + +import "fmt" + +/** +new与make的区别: +1. 二者都是用来做内存分配的。 +2. make只用于slice、map以及channel的初始化,返回的还是这三个引用类型本身; +3. 而new用于类型的内存分配,并且内存对应的值为类型零值,返回的是指向类型的指针。 +*/ +func main() { + a := 10 + b := &a + fmt.Printf("%v, %p\n", a, b) + fmt.Printf("a: %T, b: %T\n", a, b) + fmt.Printf("%v\n", *b) + modify1(a) + fmt.Printf("%v\n", a) + modify2(&a) + fmt.Printf("%v\n", a) + //Go中 引用类型的比变量不仅不要声明,还需要对其分配内存空间,否则将无法存储 + //而值类型则不需要分配内存空间 + //var m *int //未分配内存空间 + m := new(int) + *m = 150 + fmt.Println(*m) + + //var mm map[string]int//为分配内存空间 + mm := make(map[string]int) + mm["123"] = 1233 + fmt.Println(mm) +} + +func modify1(num int) { + num = 20 +} + +func modify2(num *int) { + *num = 100 +} diff --git a/Struct/exerices.go b/Struct/exerices.go new file mode 100644 index 0000000..617bbe8 --- /dev/null +++ b/Struct/exerices.go @@ -0,0 +1,24 @@ +package main + +import "fmt" + +type student struct { + name string + age int +} + +func main() { + m := make(map[string]*student) + stus := []student{ + {name: "小王子", age: 18}, + {name: "娜扎", age: 23}, + {name: "大王八", age: 9000}, + } + + for _, stu := range stus { + m[stu.name] = &stu + } + for k, v := range m { + fmt.Println(k, "=>", v.name) + } +} diff --git a/Struct/exerices2.go b/Struct/exerices2.go new file mode 100644 index 0000000..4398921 --- /dev/null +++ b/Struct/exerices2.go @@ -0,0 +1,64 @@ +package main + +import ( + "bufio" + "fmt" + "os" +) + +/** +使用“面向对象”的思维方式编写一个学生信息管理系统。 +学生有id、姓名、年龄、分数等信息 +程序提供展示学生列表、添加学生、编辑学生信息、删除学生等功能 +*/ + +type ExStudent struct { + ID, Age, Score, Name string +} + +func main() { + var str string + exStuArr := make([]ExStudent, 0, 20) + in := bufio.NewScanner(os.Stdin) + for true { + fmt.Println("=== 学生管理系统 ===") + fmt.Println("* 1. 展示学生 *") + fmt.Println("* 2. 添加学生 *") + fmt.Println("* 3. 编辑学生 *") + fmt.Println("* 4. 删除学生 *") + fmt.Println("====================") + fmt.Println("请输入编号:") + if in.Scan() { + str = in.Text() + } + switch str { + case "1": + for _, v := range exStuArr { + fmt.Printf("ID: %v\nName: %v\nAge: %v\nScore: %v\n", v.ID, v.Name, v.Age, v.Score) + } + break + case "2": + exStu := ExStudent{} + fmt.Println("请输入ID:") + if in.Scan() { + exStu.ID = in.Text() + } + fmt.Println("请输入Age:") + if in.Scan() { + exStu.Age = in.Text() + } + fmt.Println("请输入Name:") + if in.Scan() { + exStu.Name = in.Text() + } + fmt.Println("请输入Score:") + if in.Scan() { + exStu.Score = in.Text() + } + exStuArr = append(exStuArr, exStu) + for _, v := range exStuArr { + fmt.Printf("ID: %v\nName: %v\nAge: %v\nScore: %v\n", v.ID, v.Name, v.Age, v.Score) + } + } + } +} diff --git a/Struct/json.go b/Struct/json.go new file mode 100644 index 0000000..350b2c7 --- /dev/null +++ b/Struct/json.go @@ -0,0 +1,51 @@ +package main + +import ( + "encoding/json" + "fmt" +) + +type Student struct { + ID int + Gender string + Name string +} +type Class struct { + Title string + Student []*Student +} + +func main() { + c := &Class{ + Title: "101", + Student: make([]*Student, 0, 200), + } + for i := 0; i < 10; i++ { + stu := &Student{ + ID: i, + Gender: "男", + Name: fmt.Sprintf("stu%02d", i), + } + c.Student = append(c.Student, stu) + } + //for _, v := range c.Student { + // fmt.Printf("%#v\n", v) + //} + data, err := json.Marshal(c) + if err != nil { + fmt.Println("json marshal failed") + return + } + fmt.Printf("JSON:\n %s\n", data) + + str := `{"Title":"101","Student":[{"ID":0,"Gender":"男","Name":"stu00"},{"ID":1,"Gender":"男","Name":"stu01"}]}` + c1 := &Class{} + err = json.Unmarshal([]byte(str), c1) + if err != nil { + fmt.Println("json unmarshal failed") + return + } + for _, v := range c1.Student { + fmt.Printf("%#v\n", v) + } +} diff --git a/Struct/main.go b/Struct/main.go new file mode 100644 index 0000000..17ab0b4 --- /dev/null +++ b/Struct/main.go @@ -0,0 +1,20 @@ +package main + +import "fmt" + +/* +struct是值类型 +*/ + +// NewInt 类型定义 +type NewInt int + +// MyInt 类型别名 +type MyInt = int + +func main() { + var a NewInt + var b MyInt + + fmt.Printf("a: %T, b: %T\n", a, b) +} diff --git a/Struct/methord.go b/Struct/methord.go new file mode 100644 index 0000000..131fe8d --- /dev/null +++ b/Struct/methord.go @@ -0,0 +1,41 @@ +package main + +import "fmt" + +// Person +/** +Go语言中的方法(Method)是一种作用于特定类型变量的函数。 +这种特定类型变量叫做接收者(Receiver)。 +接收者的概念就类似于其他语言中的this或者 self。 +*/ +type Person struct { + name string + age int +} + +func newPerson2(name string, age int) *Person { + return &Person{ + name: name, + age: age, + } +} + +// Dream 方法 +func (p Person) Dream() { + fmt.Printf("%s 好好学习\n", p.name) +} + +//指针类型接收者 => +//1.因为结构体是值类型,当需要修改接收者中的值的时候,需要使用指针类型的接收者 +//2.接收者是拷贝代价比较大的大对象 +//3.保证一致性,如果有某个方法使用了指针接收者,那么其他的方法也应该使用指针接收者。 +func (p *Person) setAge(nAge int) { + p.age = nAge +} + +func main() { + p1 := newPerson2("song", 18) + p1.Dream() + p1.setAge(20) + fmt.Printf("p1: %v", p1.age) +} diff --git a/Struct/struct1.go b/Struct/struct1.go new file mode 100644 index 0000000..59f4ce3 --- /dev/null +++ b/Struct/struct1.go @@ -0,0 +1,50 @@ +package main + +import "fmt" + +type person struct { + city, name string + age int +} + +func main() { + //基本实例化 + var p1 person //没有初始化的结构体,其成员变量都是对应其类型的零值。 + p1.age = 10 + p1.city = "anhui" + p1.name = "ld" + + //匿名结构体 + var user struct { + name string + age int + } + user.age = 10 + user.name = "username" + fmt.Println(p1, user) + + //创建指针类型结构体 + var p2 = new(person) + fmt.Printf("p2: %T\n", p2) + fmt.Printf("p2: %#v\n", p2) + + //取结构体地址的实例化 + p3 := &person{} + fmt.Printf("p3: %T\n", p3) + fmt.Printf("p3: %#v\n", p3) + p3.age = 18 //本质在底层是执行的 (*p3).age = 18 + p3.city = "beijing" + p3.name = "zhang san" + fmt.Printf("p3: %#v\n", p3) + + p4 := newPerson("p4", "suzhou", 22) + fmt.Printf("p4: %#v\n", p4) +} + +func newPerson(name, city string, age int) *person { + return &person{ + city: city, + name: name, + age: age, + } +} diff --git a/Struct/struct2.go b/Struct/struct2.go new file mode 100644 index 0000000..eaef87e --- /dev/null +++ b/Struct/struct2.go @@ -0,0 +1,36 @@ +package main + +import "fmt" + +// Person2 匿名结构体 +type Person2 struct { + string + int +} + +// Address 嵌套结构体 +type Address struct { + Province, City string +} +type User struct { + Name string + Age int + Address +} + +func main() { + p1 := Person2{ + "132", + 18, + } + fmt.Printf("p1: %#v\n", p1) + user := User{ + Name: "song", + Age: 18, + Address: Address{ + Province: "anhui", + City: "An qing", + }, + } + fmt.Printf("%#v\n", user.City) +} diff --git a/Struct/structEx.go b/Struct/structEx.go new file mode 100644 index 0000000..d584e1f --- /dev/null +++ b/Struct/structEx.go @@ -0,0 +1,25 @@ +package main + +import "fmt" + +type Person3 struct { + name string + age int8 + dreams []string +} + +func (p *Person3) SetDreams(dreams []string) { + //p.dreams = dreams + p.dreams = make([]string, len(dreams)) + copy(p.dreams, dreams) +} + +func main() { + p1 := Person3{name: "小王子", age: 18} + data := []string{"吃饭", "睡觉", "打豆豆"} + p1.SetDreams(data) + + // 你真的想要修改 p1.dreams 吗? + data[1] = "不睡觉" + fmt.Println(p1.dreams) // ? +} diff --git a/Struct/structExtends.go b/Struct/structExtends.go new file mode 100644 index 0000000..dbddae2 --- /dev/null +++ b/Struct/structExtends.go @@ -0,0 +1,33 @@ +package main + +import "fmt" + +//Animal 动物 +type Animal struct { + name string +} + +func (a *Animal) move() { + fmt.Printf("%s会动!\n", a.name) +} + +//Dog 狗 +type Dog struct { + Feet int8 + *Animal //通过嵌套匿名结构体实现继承 +} + +func (d *Dog) wang() { + fmt.Printf("%s会汪汪汪~\n", d.name) +} + +func main() { + d1 := &Dog{ + Feet: 4, + Animal: &Animal{ //注意嵌套的是结构体指针 + name: "乐乐", + }, + } + d1.wang() //乐乐会汪汪汪~ + d1.move() //乐乐会动! +} diff --git a/Struct/structTag.go b/Struct/structTag.go new file mode 100644 index 0000000..a6fb70a --- /dev/null +++ b/Struct/structTag.go @@ -0,0 +1,33 @@ +package main + +/** +Tag是结构体的元信息,可以在运行的时候通过反射的机制读取出来。 Tag在结构体字段的后方定义,由一对反引号包裹起来,具体的格式如下: + +`key1:"value1" key2:"value2"` +*/ + +import ( + "encoding/json" + "fmt" +) + +// Student2 学生 +type Student2 struct { + ID int `json:"id"` //通过指定tag实现json序列化该字段时的key + Gender string //json序列化是默认使用字段名作为key + name string //私有不能被json包访问 +} + +func main() { + s1 := Student2{ + ID: 1, + Gender: "男", + name: "沙河娜扎", + } + data, err := json.Marshal(s1) + if err != nil { + fmt.Println("json marshal failed!") + return + } + fmt.Printf("json str:%s\n", data) //json str:{"id":1,"Gender":"男"} +}