零基础学习Go的Day04| 青训营笔记

71 阅读6分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天

Go-Day04

1.复习已学知识

  • Go中定义变量,使用var进行定义变量,const用于定义常量,go支持类型自动推断,:=定义变量的简洁写法
  • Go中使用if else,不需要加()
  • Go中使用循环,只存在for这一种循环语句
  • Go中switch语句,不需要加break,Go中case不存在穿透性这点跟Java不一样!支持任意类型
  • Go中使用数组,真实开发场景很少使用数组,因为他的长度固定,使用Go中的切片进行替代
  • Go中使用切片,使用make创建切片,使用跟数组一样,可以使用copy()拷贝A切片到B切片
  • Go中map,实际开发中使用最频繁的数据结构,在Java中叫HashMap,使用make创建map,需要指定俩个类型,第一个指定是key的类型,第二个指定的是value的类型,使用[]语法进行存取值,使用delete删除map中的元素,使用ok判断元素是否存在,Go中map是无序的
  • Go中range,切片和map可以使用range进行快速的遍历
  • Go中函数,也就是Java中的方法
  • Go中指针,用于对常用参数的修改
  • Go中结构体,有点像Java定义对象的感觉

2.学完走进Go语言基础语言的课程

  • Go中结构体方法的使用,定义分为带指针和不带指针,带指针可以对值进行修改
package main

import "fmt"

type user struct {
   name     string
   password string
}

func (u user) checkPassword(password string) bool {
   return u.password == password
}

func (u *user) resetPassword(password string) {
   u.password = password
}

func main() {
   a := user{name: "wang", password: "1024"}
   a.resetPassword("2048")
   fmt.Println(a.checkPassword("2048")) // true
}
  • Go中对错误的处理,可以在函数中定义error参数表示这个函数可能会发生错误并进行处理
package main

import (
   "errors"
   "fmt"
)

type user struct {
   name     string
   password string
}

func findUser(users []user, name string) (v *user, err error) {
   for _, u := range users {
      if u.name == name {
         return &u, nil
      }
   }
   return nil, errors.New("not found")
}

func main() {
   u, err := findUser([]user{{"wang", "1024"}}, "wang")
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(u.name) // wang

   if u, err := findUser([]user{{"wang", "1024"}}, "li"); err != nil {
      fmt.Println(err) // not found
      return
   } else {
      fmt.Println(u.name)
   }
}
  • Go中对字符串的操作,在strings包下拥有许多对字符串的操作函数
package main

import (
   "fmt"
   "strings"
)

func main() {
   a := "hello"
   fmt.Println(strings.Contains(a, "ll"))                // true
   fmt.Println(strings.Count(a, "l"))                    // 2
   fmt.Println(strings.HasPrefix(a, "he"))               // true
   fmt.Println(strings.HasSuffix(a, "llo"))              // true
   fmt.Println(strings.Index(a, "ll"))                   // 2
   fmt.Println(strings.Join([]string{"he", "llo"}, "-")) // he-llo
   fmt.Println(strings.Repeat(a, 2))                     // hellohello
   fmt.Println(strings.Replace(a, "e", "E", -1))         // hEllo
   fmt.Println(strings.Split("a-b-c", "-"))              // [a b c]
   fmt.Println(strings.ToLower(a))                       // hello
   fmt.Println(strings.ToUpper(a))                       // HELLO
   fmt.Println(len(a))                                   // 5
   b := "你好"
   fmt.Println(len(b)) // 6
}
  • Go中的字符串格式化,在标注库的fmt包下有许多字符串格式化的方法
package main

import "fmt"

type point struct {
   x, y int
}

func main() {
   s := "hello"
   n := 123
   p := point{1, 2}
   fmt.Println(s, n) // hello 123
   fmt.Println(p)    // {1 2}

   fmt.Printf("s=%v\n", s)  // s=hello
   fmt.Printf("n=%v\n", n)  // n=123
   fmt.Printf("p=%v\n", p)  // p={1 2}
   fmt.Printf("p=%+v\n", p) // p={x:1 y:2}
   fmt.Printf("p=%#v\n", p) // p=main.point{x:1, y:2}

   f := 3.141592653
   fmt.Println(f)          // 3.141592653
   fmt.Printf("%.2f\n", f) // 3.14
}
  • Go中JSON处理,需要保证结构体中每一个字段的第一个字母大写,也就是Go中的公开字段,这样定义的结构体就可以使用json.Marshal()进行序列化,使用json.Unmarshal()进行反序列化到一个空的变量中,在结构体中在定义字段的类型后面加上json:"字段名"就可以自定义json具体的返回名,类似于SpringBoot框架中Jackson的@JsonProperty的用法
package main

import (
   "encoding/json"
   "fmt"
)

type userInfo struct {
   Name  string
   Age   int `json:"age"`
   Hobby []string
}

func main() {
   a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}}
   buf, err := json.Marshal(a)
   if err != nil {
      panic(err)
   }
   fmt.Println(buf)         // [123 34 78 97...]
   fmt.Println(string(buf)) // {"Name":"wang","age":18,"Hobby":["Golang","TypeScript"]}

   buf, err = json.MarshalIndent(a, "", "\t")
   if err != nil {
      panic(err)
   }
   fmt.Println(string(buf))

   var b userInfo
   err = json.Unmarshal(buf, &b)
   if err != nil {
      panic(err)
   }
   fmt.Printf("%#v\n", b) // main.userInfo{Name:"wang", Age:18, Hobby:[]string{"Golang", "TypeScript"}}
}
  • Go中对时间的处理,使用标注库中的time库,time.now()快速获取当前时间,time.Date()构建一个自定义带时区的时间,通过.Year()获取年、.Month()获取月、.Day()获取天、.Hour()获取时、.Minute()获取分,使用.sub()可以对俩个时间进行相减得到相差的时间,使用.Format("2006-01-02 15:04:05")进行时间格式化,使用.Unix()获取时间的时间戳
package main

import (
   "fmt"
   "time"
)

func main() {
   now := time.Now()
   fmt.Println(now) // 2022-03-27 18:04:59.433297 +0800 CST m=+0.000087933
   t := time.Date(2022, 3, 27, 1, 25, 36, 0, time.UTC)
   t2 := time.Date(2022, 3, 27, 2, 30, 36, 0, time.UTC)
   fmt.Println(t)                                                  // 2022-03-27 01:25:36 +0000 UTC
   fmt.Println(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute()) // 2022 March 27 1 25
   fmt.Println(t.Format("2006-01-02 15:04:05"))                    // 2022-03-27 01:25:36
   diff := t2.Sub(t)
   fmt.Println(diff)                           // 1h5m0s
   fmt.Println(diff.Minutes(), diff.Seconds()) // 65 3900
   t3, err := time.Parse("2006-01-02 15:04:05", "2022-03-27 01:25:36")
   if err != nil {
      panic(err)
   }
   fmt.Println(t3 == t)    // true
   fmt.Println(now.Unix()) // 1648738080
}
  • Go中对数字的解析,引入strconv库,strconv.ParseFloat()格式化为浮点数,strconv.ParseInt()格式化为整数
package main

import (
   "fmt"
   "strconv"
)

func main() {
   f, _ := strconv.ParseFloat("1.234", 64)
   fmt.Println(f) // 1.234

   n, _ := strconv.ParseInt("111", 10, 64)
   fmt.Println(n) // 111

   n, _ = strconv.ParseInt("0x1000", 0, 64)
   fmt.Println(n) // 4096

   n2, _ := strconv.Atoi("123")
   fmt.Println(n2) // 123

   n2, err := strconv.Atoi("AAA")
   fmt.Println(n2, err) // 0 strconv.Atoi: parsing "AAA": invalid syntax
}
  • Go中获取进程信息
package main

import (
   "fmt"
   "os"
   "os/exec"
)

func main() {
   // go run example/20-env/main.go a b c d
   fmt.Println(os.Args)           // [/var/folders/8p/n34xxfnx38dg8bv_x8l62t_m0000gn/T/go-build3406981276/b001/exe/main a b c d]
   fmt.Println(os.Getenv("PATH")) // /usr/local/go/bin...
   fmt.Println(os.Setenv("AA", "BB"))

   buf, err := exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput()
   if err != nil {
      panic(err)
   }
   fmt.Println(string(buf)) // 127.0.0.1       localhost
}

总结

1.学会了定义结构体方法,但是定义分为带指针和不带指针,带指针可以对值进行修改
2.学会了对错误的处理,可以在函数中定义error参数表示这个函数可能会发生错误并进行处理
3.学会了对字符串的操作,在strings包下拥有许多对字符串的操作函数,对字符串格式化操作,在标注库的fmt包下有许多字符串格式化的方法
4.学会了JSON处理,需要保证结构体中每一个字段的第一个字母大写,也就是Go中的公开字段,这样定义的结构体就可以使用json.Marshal()进行序列化,使用json.Unmarshal()进行反序列化到一个空的变量中,在结构体中在定义字段的类型后面加上json:"字段名"就可以自定义json具体的返回名,类似于SpringBoot框架中Jackson的@JsonProperty的用法
5.对时间的处理,使用标注库中的time库,time.now()快速获取当前时间,time.Date()构建一个自定义带时区的时间,通过.Year()获取年、.Month()获取月、.Day()获取天、.Hour()获取时、.Minute()获取分,使用.sub()可以对俩个时间进行相减得到相差的时间,使用.Format("2006-01-02 15:04:05")进行时间格式化,使用.Unix()获取时间的时间戳
6.对数字的解析,引入strconv库,strconv.ParseFloat()格式化为浮点数,strconv.ParseInt()格式化为整数
7.在Go中获取进程信息