Go 基础 02

  • 结构体排序
 1 package main
 2 
 3 import (
 4     "fmt"
 5     "math/rand"
 6     "sort"
 7 )
 8 
 9 type Student struct {
10     Name string
11     Id   string
12     age  int
13 }
14 
15 type Book struct {
16     Name   string
17     Author string
18 }
19 
20 // 通过接口实现标准库中 sort 的 Sort 方法
21 // 定义一个 Student 类型的切片,名字叫 StudentArray
22 type StudentArray []Student
23 
24 // 返回 Student 类型的切片长度
25 func (p StudentArray) Len() int {
26     return len(p)
27 }
28 
29 // 返回 Student 类型的切片 i j 位置姓名字符串比较的结果
30 func (p StudentArray) Less(i, j int) bool {
31     // 从大到小排序
32     // return p[i].Name > p[j].Name
33     // 从小到大排序
34     return p[i].Name < p[j].Name
35 }
36 
37 // 交换 i j 位置
38 func (p StudentArray) Swap(i, j int) {
39     p[i], p[j] = p[j], p[i]
40 }
41 
42 func main() {
43     var stus StudentArray
44     // 向 StudentArray 中赋值
45     for i := 0; i < 10; i++ {
46         stu := Student{
47             Name: fmt.Sprintf("stu%d", rand.Intn(100)),
48             Id:   fmt.Sprintf("110%d", rand.Intn(100)),
49             age:  rand.Intn(100),
50         }
51         stus = append(stus, stu)
52     }
53     // 遍历 StudentArray 并打印值
54     for _, v := range stus {
55         fmt.Println(v)
56     }
57     fmt.Println()
58     // 排序
59     sort.Sort(stus)
60     // 遍历 StudentArray 并打印值
61     for _, v := range stus {
62         fmt.Println(v)
63     }
64 }
  • 通用链表
 1 // link.go
 2 
 3 package main
 4 
 5 import (
 6     "fmt"
 7 )
 8 
 9 // 通用链表
10 // 链表中的一个节点
11 type LinkNode struct {
12     // 空接口(任何类型都已经实现空接口)
13     // 也就是任何类型的变量都可以赋值给空接口
14     data interface{}
15     // 指向后面节点的指针
16     next *LinkNode
17 }
18 
19 // 链表
20 type Link struct {
21     // 指向头节点的指针
22     head *LinkNode
23     // 指向尾节点的指针
24     tail *LinkNode
25 }
26 
27 // 节点从头部插入
28 func (p *Link) InsertHead(data interface{}) {
29     // 生成新的节点
30     node := &LinkNode{
31         data: data,
32         next: nil,
33     }
34 
35     // 当头指针和尾指针都为空时,表示此时的链表为空链表
36     if nil == p.tail && nil == p.head {
37         p.tail = node
38         p.head = node
39         return
40     }
41 
42     // 新的节点的 next 要等于头节点
43     node.next = p.head
44     // 更新头部指针,使头部指针重新指向新的节点
45     p.head = node
46 
47 }
48 
49 // 节点从尾部插入
50 func (p *Link) InsertTail(data interface{}) {
51     // 生成新的节点
52     node := &LinkNode{
53         data: data,
54         next: nil,
55     }
56     // 当头指针和尾指针都为空时,表示此时的链表为空链表
57     if nil == p.tail && nil == p.head {
58         p.tail = node
59         p.head = node
60         return
61     }
62 
63     // 之前尾部节点的 next 指向新的节点
64     p.tail.next = node
65     // 更新尾部指针,指向新节点
66     p.tail = node
67 }
68 
69 // 遍历链表
70 func (p *Link) Trans() {
71     q := p.head
72     for nil != q {
73         fmt.Println(q.data)
74         q = q.next
75     }
76 }
 1 // main.go
 2 
 3 package main
 4 
 5 import (
 6     "fmt"
 7 )
 8 
 9 func main() {
10     var headLink Link
11     // 从头部插入10个节点(逆序)
12     for i := 0; i < 10; i++ {
13         headLink.InsertHead(fmt.Sprintf("crixus_%d", i))
14     }
15     headLink.Trans()
16     fmt.Println()
17     var tailLink Link
18     // 从尾部插入10个节点(顺序)
19     for i := 0; i < 10; i++ {
20         tailLink.InsertTail(fmt.Sprintf("crixus_%d", i))
21     }
22     tailLink.Trans()
23 }
  • 通过反射操作结构体
 1 package main
 2 
 3 import (
 4     "encoding/json"
 5     "fmt"
 6     "reflect"
 7 )
 8 
 9 type Student struct {
10     Name  string `json:"student_name"`
11     Age   int
12     Score float32
13     Sex   string
14 }
15 
16 func (s Student) Print() {
17     fmt.Println(s)
18 }
19 
20 func (s Student) Set(name string, age int, score float32, sex string) {
21     s.Name = name
22     s.Age = age
23     s.Score = score
24     s.Sex = sex
25 }
26 
27 // 通过反射操作结构体
28 func TestStruct(a interface{}) {
29     // 获取指定字段的 tag 标签
30     typ := reflect.TypeOf(a)
31     tag := typ.Elem().Field(0).Tag.Get("json")
32     fmt.Printf("tag => %s\n", tag)
33 
34     // 获取指定字段的 name 标签
35     name := typ.Elem().Field(1).Name
36     fmt.Printf("name => %s\n", name)
37 
38     val := reflect.ValueOf(a)
39     // 获取类别
40     kd := val.Kind()
41     // 当类别不为结构体,就不再进行分析,直接退出
42     if reflect.Ptr != kd && reflect.Struct == val.Elem().Kind() {
43         fmt.Println("not struct ...")
44         return
45     }
46     // 获取结构体中字段的数量
47     num := val.Elem().NumField()
48     fmt.Printf("struct has %d fields\n", num)
49 
50     // 修改结构体中指定字段的值
51     val.Elem().Field(0).SetString("crixus")
52 
53     // 遍历结构体中字段的值
54     for i := 0; i < num; i++ {
55         fmt.Printf("Field %d : Kind %v : %v => %v\n", i, val.Elem().Field(i).Kind(), typ.Elem().Field(i).Name, val.Elem().Field(i))
56     }
57 
58     // 获取结构体中方法的数量
59     numOfMethod := val.Elem().NumMethod()
60     fmt.Printf("struct has %d method\n", numOfMethod)
61 
62     // 调用结果体中的方法
63     var params []reflect.Value
64     val.Elem().Method(0).Call(params)
65 }
66 
67 func main() {
68     var a Student = Student{
69         Name:  "stu01",
70         Age:   18,
71         Score: 92.5,
72         Sex:   "female",
73     }
74     // 通过 json 打包结构体
75     // result 是字节数组
76     result, _ := json.Marshal(a)
77     // 输出时,result 字节数组转字符串
78     fmt.Println("Json result =>", string(result))
79     TestStruct(&a)
80 }
  • 文件拷贝
 1 package main
 2 
 3 import (
 4     "fmt"
 5     "io"
 6     "os"
 7 )
 8 
 9 func main() {
10 
11     // 相对路径
12     _, err := CopyFile("target.txt", "source.txt")
13     if nil != err {
14         fmt.Println("Copy failed ...", err)
15         return
16     }
17     fmt.Println("Copy done ...")
18 }
19 
20 // 文件拷贝
21 func CopyFile(dstName, srcName string) (written int64, err error) {
22     // 读文件
23     src, err := os.Open(srcName)
24     if nil != err {
25         return
26     }
27     defer src.Close()
28 
29     // 写文件
30     dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644)
31     if nil != err {
32         return
33     }
34     defer dst.Close()
35 
36     return io.Copy(dst, src)
37 }
  • 结构体序列化和反序列化
 1 package main
 2 
 3 import (
 4     "encoding/json"
 5     "fmt"
 6 )
 7 
 8 type User struct {
 9     UserName string `json:"username"`
10     NickName string
11     Age      int
12     Birthday string
13     Sex      string
14     Email    string
15     Phone    string
16 }
17 
18 func testStruct() (ret string, err error) {
19     user1 := &User{
20         UserName: "user01",
21         NickName: "Crixus01",
22         Age:      18,
23         Birthday: "2019-02-12",
24         Sex:      "male",
25         Email:    "280247844@qq.com",
26         Phone:    "12345678901",
27     }
28 
29     // json.Marshal 执行后返回字节数组
30     data, err := json.Marshal(user1)
31     if nil != err {
32         err = fmt.Errorf("json.marshal failed, err :", err)
33         return
34     }
35     // 字节数组转为字符串
36     ret = string(data)
37     return
38 }
39 
40 // json 串反序列化为结构体
41 func test() {
42     data, err := testStruct()
43     if nil != err {
44         fmt.Println("test struct failed ...")
45     }
46     var user1 User
47     // 字符串转为字符串字节数组
48     // 结构体是值类型,要更新其中字段需要传地址进去
49     err = json.Unmarshal([]byte(data), &user1)
50     if nil != err {
51         fmt.Println("Unmarshal failed ...")
52     }
53     fmt.Println(user1)
54 }
55 
56 func main() {
57     // json 串反序列化为结构体
58     test()
59 }

 

(  Over  )

posted @ 2019-02-13 09:07  Crixus3714  阅读(152)  评论(0编辑  收藏  举报