字节青训营第一天笔记-Go基本语法

52 阅读5分钟

Go 基础语法与工程实践、性能调优、设计模式、语言笔记服务

一, Go&GoLand下载使用

  • 注意!!:在go语言编译的时候,如果只是单单编译一个文件的话,package必须是main,意味着是可以单独编译的

二, Go语法基础

  • Go语言的特点
  • Go语言的运用场景
  • 字节使用Go的原因
  • Go基础推荐网站:Go 语言之旅
//Go程序从 main 包开始运行。
package main

//通过导入路径 "fmt" 和 "math/rand" 来使用这两个包
import (
        "fmt"
        "math/rand"
)
/*
也可以编写多个导入语句,例如:
import "fmt"
import "math"
不推荐使用这种方式*/
func main() {
         //包名与导入路径的最后一个元素一致。例如,"math/rand" 包中的源码均以 package rand 语句开始。
        fmt.Println("My favorite number is", rand.Intn(10))
       
        //Go 中,如果一个名字以大写字母开头,那么它就是已导出的,否则报错: undefined:
        //fmt.Println("My favorite number is", rand.intn(10))
}
  1. 变量

package main

import (
    "fmt"
    "math"
)

func main() {
    //定义变量,自动推导类型为string
    var a = "inittial"
    //也可以指定变量类型 ,b,c均为int
    var b, c int = 1, 2
    //bool类型
    var d = true

    //定义变量e, 不初始化, 但默认为0
    var e float64
    //:= 使用已有变量进行赋值
    f := float32(e)
    //字符串可以用+拼接
    g := a + "foo"
    fmt.Println(a, b, c, d, e, f)
    fmt.Println(g)
    
    //定义常量,指定类型
    const s string = "constant"
    //也可以不指定类型
    const h = 500000000
    
    const i = 3e20 / h
    fmt.Println(s, h, i, math.Sin(h), math.Sin(i))
}
  1. 分支语句if

package main

import "fmt"

func main() {
    //if后没有括号
    //if后必须使用{}
    if 7%2 == 0 {
       fmt.Println("7is even")
    } else {
       fmt.Println("7 is odd")
    }

    if 8%4 == 0 {
       fmt.Println("8 is divisible by 4")
    }

    if num := 9; num < 0 {
       fmt.Println(num, "is negative")
    } else if num < 10 {
       fmt.Println(num, "has 1 digit")
    } else {
       fmt.Println(num, "has mutiple digits")
    }
}
  1. 分支语句switch

package main

import (
    "fmt"
    "time"
)

func main() {
    a := 2
    switch a {
    //默认执行完case后break
    case 1:
       fmt.Println("one")
    case 2:
       fmt.Println("two")
    default:
       fmt.Println("other")
    }
    t := time.Now()
    switch {
    //case可以使用表达式
    case t.Hour() < 12:
       fmt.Println("Is is before noon")
    default:
       fmt.Println("Is is after noon")

    }
}
  1. 循环语句for

package main

import "fmt"

func main() {
    i := 1
    //死循环
    for {
       fmt.Println("loop")
       //跳出循环
       break
    }
    //经典c循环
    for j := 7; j < 9; j++ {
       fmt.Println(j)
    }

    for n := 0; n < 5; n++ {
       if n%2 == 0 {
          //继续循环
          continue
       }
       fmt.Println(n)
    }

    for i <= 3 {
       fmt.Println(i)
       i = i + 1
    }
}
  1. 数组

package main

import (
    "fmt"
)

func main() {

    var a [5]int
    a[4] = 100
    fmt.Println(a[4], len(a))

    b := [5]int{1, 2, 3, 4, 5}
    fmt.Println(b)

    var twoD [2][3]int
    for i := 0; i < 2; i++ {
       for j := 0; j < 3; j++ {
          twoD[i][j] = i + 1
       }
    }
    fmt.Println("2d:", twoD)
}

定长,所以实际开发不常用

  1. 切片

package main

import "fmt"

func main() {
    //make创建切片
    s := make([]string, 3)
    s[0] = "a"
    s[1] = "b"
    s[2] = "c"
    fmt.Println("get:", s[2])
    fmt.Println("eln:", len(s))

    //必须把结构赋值会s,因为内存不够时会移动物理内存
    s = append(s, "d")
    //不定参数
    s = append(s, "e", "f")
    fmt.Println(s)

    c := make([]string, len(s))
    copy(c, s)
    //支持切片操作
    fmt.Println(s[2:5])
    fmt.Println(s[:5])
    fmt.Println(s[2:])

    good := []string{"g", "o", "o", "d"}
    fmt.Println(good)
}
  1. map

package main

import "fmt"

func main() {

    m := make(map[string]int)
    m["one"] = 1
    m["two"] = 2
    fmt.Println(m)
    fmt.Println(len(m))
    fmt.Println(m["one"])
    fmt.Println(m["unknown"])

    //ok获取键是否存在
    r, ok := m["unknown"]
    fmt.Println(r, ok)

    delete(m, "one")

    m2 := map[string]int{"one": 1, "two": 2}
    var m3 = map[string]int{"one": 1, "two": 2}
    fmt.Println(m2, m3)
}
  1. Range

package main

import (
    "fmt"
)

func main() {
    nums := []int{2, 3, 4}
    sum := 0
    for i,num:=range nums{
       sum+=num
       if num==2 {
          fmt.Println("index:",i ,"num:",num)
       }
    }
    fmt.Println(sum)
    
    m:=map[string]string{"a":"A","b":"B"}
    for k,v :=range m{
       fmt.Println(k,v)
    }
    for k := range m{
       fmt.Println("key:",k)
    }
}
  1. 函数

package main

import "fmt"

func add(a int, b int) int {
    return a + b
}
func add2(a, b int) int {
    return a + b
}
func exists(m map[string]string, k string) (v string, ok bool) {
    v, ok = m[k]
    return v, ok
}
func main() {
    res := add(1, 2)
    fmt.Println(res)
    v, ok := exists(map[string]string{"a": "A"}, "a")
    fmt.Println(v,ok)
}
  1. 指针

package main

import "fmt"

func add2(n int) {
    n += 2
}

func add2ptr(n *int) {
    *n += 2
}
func main() {
    n := 5
    //值传递,不改变n得知
    add2(n)
    fmt.Println(n)
    //地址传递,用&取地址
    add2ptr(&n)
    fmt.Println(n)
}
  1. 结构体

package main

import (
    "fmt"
)

type user struct {
    name string
    password string
}

func main() {
    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"
    fmt.Println(a,b,c,d)
    fmt.Println()
}
func checkPassword(u user,password string) bool {
    return u.password == password
}
func checkPassword2(u *user, password string) bool {
    return u.password ==password
}
  1. 结构体方法

package main

import (
    "fmt"
)

type user struct {
    name     string
    password string
}

func main() {
    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"
    fmt.Println(a, b, c, d)
    fmt.Println()
}
func(u user) checkPassword( password string) bool {
    return u.password == password
}
func(u *user) checkPassword2( password string) bool {
    return u.password == password
}
  1. 错误处理

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)

    if u, err := findUser([]user{{"wang", "1024"}}, "li"); err != nil {
       fmt.Println(err)
       return
    } else {
       fmt.Println(u.name)
    }
}
  1. 时间处理

package main

import (
    "fmt"
    "time"
)

type user struct {
    name     string
    password string
}

func main() {

    now := time.Now()
    fmt.Println(now)

    t := time.Date(2022, 3, 27, 1, 25, 36, 0, time.UTC)
    t2 := time.Date(2022, 3, 27, 2, 25, 36, 0, time.UTC)
    fmt.Println(t.Year(), t.Minute(), t.Day(), t.Hour(), t.Minute())
    fmt.Println(t.Format(time.DateTime)) //time.DateTime 就是 "2006-01-02 15:04:05"
    fmt.Println("2006-01-02 15:04:05")
    diff := t2.Sub(t)
    fmt.Println(diff)
    fmt.Println(diff.Minutes(), diff.String())
    
    //按 "2006-01-02 15:04:05" 的格式包装右边参数
    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)
    
    //获取时间戳
    fmt.Println(now.Unix())
}
  • 字符串与数字转换
package main

import (
    "fmt"
    "strconv"
)

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

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

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

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

    n2, err := strconv.Atoi("AAA")
    fmt.Println(n2, err)
}
  1. 字符串格式化

package main

import "fmt"

type point struct {
    x, y int
}

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

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

}
  1. 字符串操作

package main

import (
    "fmt"
    "strings"
)

func main() {
    a := "hello"
    fmt.Println(strings.Contains(a, "ll"))
    fmt.Println(strings.Count(a, "l"))
    fmt.Println(strings.HasPrefix(a, "he"))
    fmt.Println(strings.HasSuffix(a, "llo"))
    fmt.Println(strings.Index(a, "ll"))
    fmt.Println(strings.Join([]string{"he", "ll", "o"}, "-"))
    fmt.Println(strings.Repeat(a, 2))
    fmt.Println(strings.Replace(a, "e", "E", -1))
    fmt.Println(strings.SplitAfter("a-b-c", "-"))
    fmt.Println(strings.ToLower(a))
    fmt.Println(strings.ToUpper(a))
    fmt.Println(len(a))

    //中文会占更多长度
    b := "你好"
    fmt.Println(len(b))
}
  1. Json操作

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)
    fmt.Println(string(buf))

    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)
}
  1. 进程信息

package main

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

func main() {

    fmt.Println(os.Args)
    fmt.Println(os.Getenv("PATH"))
    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))

}