Golang基础语法|青训营笔记

85 阅读6分钟

这是我参与[第三届青训营-后端场]笔记创作活动的第一次笔记~

GO语法与C++或其他语言对比

  • 1 go中同样有main函数,不过go的main函数必须在开始处使用package main来定义
  • 2 go 中可以导入包,类比C++中的#include ,go中包的导入类似于python的包的导入:

    • 例如(go的包的导入):import (
          "fmt"
  • 3 go 中的变量定义

    • 使用var定义变量

      • 例如:
            var a = "initial"  定义了一个字符串类型的a变量
            var b, c int = 1, 2 定义了两个整形的变量b, c(注:与C++相比,相当于把变量的类型放到了后面,然后赋值按顺序进行赋值)
        
    • 使用 :=定义变量

      • 例如:
            var e float64
            f := float32(e):定义变量f
            
            
        注::= 定义变量时只能在函数内部,包括方法内
        
    • 常量定义

      • go的常量定义类似于C++,使用const
        例如:
            const s string = "constant"
        
  • go中的输出函数

    • go的输出函数有fmt.Println()[注:需要先导入fmt包],该函数类似于C的printf函数,只是该函数自动输出换行,C需要输入"\n"才能换行
      
  • go的除法

    • go的除法运算和C++类似,即8/5表示取得整数部分1
      
  • go的循环

    • go中没有while循环,go只有for循环,不过gofor循环有多种使用方法,可以达到类似while的使用
      例如:
          例一:
          for { //注:此种for循环就类似于C++的while(1)
              fmt.Println("loop")
              break
          }
          例二:
          for j := 7; j < 9; j++ {//此种for循环就和正常的C++ for循环差不多,只是for循环不带括号
              fmt.Println(j)
          }
          例三:
          for i <= 3 {//此种for循环就和C++的while(i <= 3)代表同样的含义
              fmt.Println(i)
              i = i + 1
          }
          总结:gofor循环非常灵活,即go中的for循环可以达到C++中的for循环和while的两种效果
      
  • go的条件语句

    • go的条件语句同样比较灵活,有以下几种用法
      例一:
          if 7%2 == 0 {//该语句和C++的if,else语句类似,区别在于go中if的条件不用括号
              fmt.Println("7 is even")
          } else {
              fmt.Println("7 is odd")
          }
      例二:
          if num := 9; num < 0 {//此种方式是go独有的,即可以在if后面进行临时变量的简单定义
              fmt.Println(num, "is negative")
          } else if num < 10 {
              fmt.Println(num, "has 1 digit")
          } else {
              fmt.Println(num, "has multiple digits")
          }
      
  • go中switch语句

    • 1 go中的switch语句与C++的switch语句的区别在于,go中的switch语句不需要再每个条件下加break,不加时执行完该条件同样会跳出。
      2 go中同样有default
      3 go中的switchcase部分可以是表达式
      例一:
          a := 2
          switch a {
              case 1:
                  fmt.Println("one")
              case 2:
                  fmt.Println("two")
              case 3:
                  fmt.Println("three")
              case 4, 5:
                  fmt.Println("four or five")
              default:
                  fmt.Println("other")
              }
      例二:
          t := time.Now()
          switch {
          case t.Hour() < 12:
              fmt.Println("It's before noon")
          default:
              fmt.Println("It's after noon")
          }
      
  • go的数组定义

    • 1 go的数组定义与C++类似,只是go的数组的定义遵循go的变量定义的规则
      例一:
          var a [5]int //一位数组定义
          var twoD [2][3]int  //二维数组定义
      2 go的数组元素的访问和C++相同
      ​
      注:go的fmt.Println可以直接打印数组
      
  • go切片(slice)

    • 由内置函数make创建切片

      • 注:有make创建的切片各元素被默认初始化为切片元素类型的零值。
        例一:
            s := make([]string, 3)//创建字符串切片,相当于C++的string s[3],即三个string类型的数组
        例二:
            c := make([]string, len(s))
            copy(c, s)//即可以利用copy函数将s的元素拷贝到c中
        例三:
            go的切片和python类似,支持以下方式
            假设s = [a b c d e f]
            则s[2:5] 为 [c d e f]
            s[:]和s一样
            s[:2]为 [a b]
            s[2:]和s[2:5]相同
        例四:
            good := []string{"g", "o", "o", "d"}//创建时初始化
            
        注:可以使用内置函数 append,copy
        例:
            s = append(s, "d")
            s = append(s, "e", "f")
        
  • go的map

    • 定义及访问如下,和C++类似
      例一:
          m := make(map[string]int)
          m["one"] = 1
          m["two"] = 2
      例二:
          r, ok := m["unknow"]//go中独有的方式  其中m没有健"unknow",因此默认返回0 和 false
          fmt.Println(r, ok) // 0 false
      例三:
          m2 := map[string]int{"one": 1, "two": 2}
          var m3 = map[string]int{"one": 1, "two": 2}
      
  • go的range函数

    • 例一:
          nums := []int{2, 3, 4}
          sum := 0
          for i, num := range nums {
              sum += num
              if num == 2 {
                  fmt.Println("index:", i, "num:", num) // index: 0 num: 2
              }
          }
          其中,第一个i表示数组nums的索引,第二个表示nums[i]的值
      例二:
          m := map[string]string{"a": "A", "b": "B"}
          for k, v := range m {
              fmt.Println(k, v) // b 8; a A
          }
          其中,第一个k表示键,第二个v表示值
      例三:
          for k := range m {
              fmt.Println("key", k) // key a; key b
          }
          其中,如果m是个字典,则k表示键,m是个数组,则k表示索引
      
  • go的函数定义

    • go的函数定义和C++类似,不过有以下几点区别
       1 定义函数时在开头使用func 关键字
       2 定义函数时,函数的返回类型在形参的括号后指出
       3 定义函数时,如果函数的形参列表类型相同,则可以省略前面的变量类型
          例如:
              func add2(a, b int) int {
                  return a + b
              }
       4 定义函数时,可以自定义返回的格式
          例如:
              func exists(m map[string]string, k string) (v string, ok bool) {
                  v, ok = m[k]
                  return v, ok
              }
      
  • go同样有指针,go的指针大致与C++相同

  • go中的结构体

    • 结构体的定义

      • go中的结构体使用type关键字进行定义,例如:
            type user struct {
                name     string
                password string
            }
        1 使用结构体定义并初始化变量的几种方法:
            a := user{name: "wang", password: "1024"}
            b := user{"wang", "1024"} //保持和结构体一致
            c := user{name: "wang"}
            c.password = "1024"
            var d user
            d.name = "wang"
            d.password = "1024"
        
    • 为自定义的结构体定义方法

      • 注:该功能是go独有的,拿此例来说,为user这个自定义结构体定义一个方法,则使用该结构体定义的变量都可以访问该方法。
        ​
        例一:
            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 的错误处理

    • //go的错误处理格式
      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
          }
          ...
      }
      

GO函数

string

strings.Contains,strings.Count,strings.HasPrefix,strings.HasSuffix,strings.Index,strings.Join,strings.Repeat,strings.Replace,strings.Split,strings.ToLower,strings.ToUpper

fmt

fmt.Println,fmt.Printf
注:Println不带格式化操作,Printf可以进行格式化输出(可以把该函数当做C语言的printf,只是把格式化输出符改变一下),格式化符如下:
    %v:格局类型格式显示数据 如 s = "hello",则输出hello  s = 123,则输出123
    %+v:先输出字段类型,再输出该字段的值
    %#v:先输出结构体名字值,再输出结构体(字段类型+字段的值)
    %.2f 同C++

json

显示为json格式
API:json.Marshal,json.MarshalIndent,json.Unmarshal
例:
    假设有结构体:
        type userInfo struct {
            Name  string
            Age   int `json:"age"`
            Hobby []string
        }
        有变量:a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}}
        经过函数json.Marshal处理a后,处理的返回值为下图1
        buf, err := json.Marshal(a)
        经过函数json.MarshalIndent处理a后,如下图2
        buf, err = json.MarshalIndent(a, "", "\t")
        经过函数json.Unmarshal处理a后,如下图3
        err = json.Unmarshal(buf, &b)

图1(buf) image.png

图1(string(buf)) image.png

图2(string(buf)) image.png

图3(b) image.png

time

time.Now,time.Date
例:
    t := time.Date(2022, 3, 27, 1, 25, 36, 0, time.UTC)
    t.Year,t.Month,t.Day,t.Hour,t.Minute,t.Sub

strconv

strconv.ParseFloat,strconv.ParseInt,strconv.ParseInt,strconv.Atoi,strconv.Atoi