青训营X豆包MarsCode 技术训练营第一课|Go语言基础语法

163 阅读6分钟

go语言优势

  1. 高性能高并发
  2. 语法简单,学习曲线平缓
  3. 丰富的标准库
  4. 完善的工具链
  5. 静态链接
  6. 快速编译
  7. 跨平台
  8. 垃圾回收

go语言入门

之前做过详细笔记([Go]基本语法 | YC's Blog),不多做赘述,只记一下有点生疏的

错误处理

errors包

在返回值中加一个 err ,可以由 errors.New("...") 创建

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")
}

在调用这个函数后,要先判断err是否为空

func main() {
​
    users := []user{
        {"kqlxk", 18},
        {"ycccc", 15},
    }
​
    u1, err := findUser(users, "yc")
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    fmt.Println(u1)
​
}

字符串操作

strings包

func main(){
    a := "hello"
    strings.Contains(a, "ll")                       //是否包含某个字符串
    strings.Count(a, "l")                           //a中有几个l
    strings.HasPrefix(a, "he")                      //a是否以he开头
    strings.HasSuffix(a, "llo")                     //a是否以llo结尾
    strings.Index(a, "ll")                          //ll的第一个位置
    strings.Join([]string{"he", "llo"}, "-")        //用"-"把切片中的字符串连起来
    strings.Repeat(a, 2)                            //返回重复两次的a
    strings.Replace(a, "e", "E", -1)                //将所有e换成E,-1表示所有
    strings.Split("a-b-c", "-")                     //用字符串中的-符号分割字符串
    strings.ToUpper(a)                              //全部大写
    strings.ToLower(a)                              //全部小写
}

JSON处理

encoding/json包

package main
​
import (
    "encoding/json"
    "fmt"
)
​
type user struct {
    name string
    age  int
}
​
func main() {
​
    buf, err := json.Marshal(user{"kqlxk", 18})
    if err != nil {
        panic(err)
        return
    }
    fmt.Println(buf)
​
    buf, err = json.MarshalIndent(user{"kqlxk", 18}, "", "\t")
    if err != nil {
        panic(err)
        return
    }
    fmt.Println(buf)
​
    var userinfo user
    err = json.Unmarshal(buf, &userinfo)
    if err != nil {
        panic(err)
        return
    }
    fmt.Println(userinfo)
​
}
​
  • json.Marshal :用于将 Go 数据结构(如结构体、切片、字典等)编码为 JSON 格式的函数

    func Marshal(v interface{}) ([]byte, error)
    
  • json.MarshalIndent:用于将数据结构编码为格式化(缩进)JSON

    func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)
    
  • json.Unmarshal:用于将json格式的数据反序列化成go语言中的数据结构

    func Unmarshal(data []byte, v interface{}) error
    

时间处理

time包

package main
​
import (
    "fmt"
    "time"
)
​
func main() {
    now := time.Now()
    fmt.Println(now)
    t := time.Date(2024, 11, 2, 21, 33, 0, 0, time.UTC)
    t2 := time.Date(2024, 11, 2, 22, 14, 0, 0, time.Local)
    fmt.Println(t)
    fmt.Println(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second())
    fmt.Println(t.Format("2006-01-02 15:04:05"))
    diff := t2.Sub(t)
    fmt.Println(diff)
    fmt.Println(diff.Minutes(), diff.Hours(), diff.Seconds())
    t3, err := time.Parse("2006-01-02 15:04:05", "2024-11-02 22:14:00")
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(t3 == t)
    fmt.Println(now.Unix())
}
​
  • time.Now() : 获取当前的本地时间。

    func Now() Time
    
  • time.Date : 创建指定时间

    func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time
    
  • time.Format():将时间 t 格式化为字符串,传入的是具体格式

    func (t Time) Format(layout string) string
    
  • time.sub():计算 t2 和 t 之间的时间差

    func (t Time) Sub(u Time) Duration
    
  • time.Parse():将给定的时间字符串解析为 time.Time 对象

    func Parse(layout, value string) (Time, error)
    
  • now.Unix() :当前时间的 Unix 时间戳(自 1970 年 1 月 1 日起的秒数)

    func (t Time) Unix() int64
    

数字解析

strconv包

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
​
}
  • strconv.ParseFloat() :将字符串转换为 float64 类型。

    func ParseFloat(s string, bitSize int) (float64, error)
    
  • strconv.ParseInt() : 将字符串转换为整数, 默认使用十六进制

    func ParseInt(s string, base int, bitSize int) (i int64, err error)
    
  • strconv.Atoi() : 使用 Atoi 函数直接将字符串转换为整数,默认使用十进制

    func Atoi(s string) (int, error)
    

进程信息

os包

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/n34xxfnx38d98bv_x8162t_m0000gn/T/go-build3406891276/b001/exe/main a b c d]  
    fmt.Println(os.Getenv("PATH"))  
    fmt.Println(os.Getenv("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
}

实战

猜数字游戏

package main
​
import (
    "bufio"
    "fmt"
    "math/rand"
    "os"
    "strconv"
    "strings"
    "time"
)
​
func main() {
​
    maxNum := 100
    //生成随机数
    r := rand.New(rand.NewSource(time.Now().UnixNano()))
    num := r.Intn(maxNum)
​
    for {
        fmt.Println("请输入你猜的数字:")
        reader := bufio.NewReader(os.Stdin)
        input, err := reader.ReadString('\n')
        if err != nil {
            panic(err)
        }
        input = strings.TrimSuffix(input, "\n")
​
        guessNum, err := strconv.Atoi(input)
        if err != nil {
            panic(err)
        }
        fmt.Println("你猜的数字是:", guessNum)
​
        if guessNum > num {
            fmt.Println("猜大了")
        } else if guessNum < num {
            fmt.Println("猜小了")
        } else {
            fmt.Println("猜对了")
            break
        }
    }
​
}

在线词典

实现一个简单的英文单词查询工具,用过调用彩云小译的api来获取单词的中文翻译

package main
​
import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "log"
    "net/http"
    "os"
)
​
// DictRequest 定义了发送到彩云小译API的请求结构体
type DictRequest struct {
    TransType string `json:"trans_type"` // 翻译类型,这里是从英文到中文
    Sourse    string `json:"source"`      // 要翻译的源语言文本,这里是英文单词
    UserID    string `json:"user_id"`     // 用户ID,这里没有使用
}
​
// DictResponse 定义了从彩云小译API返回的响应结构体
type DictResponse struct {
    Rc   int `json:"rc"`   // 返回码,表示请求是否成功
    Wiki struct {
    } `json:"wiki"` // 维基百科相关信息,这里没有使用
    Dictionary struct {
        Prons struct {
            EnUs string `json:"en-us"` // 美式英语发音
            En   string `json:"en"`    // 英式英语发音
        } `json:"prons"` // 发音信息
        Explanations []string      `json:"explanations"` // 解释,即单词的中文翻译
        Synonym      []string      `json:"synonym"`      // 同义词
        Antonym      []string      `json:"antonym"`      // 反义词
        WqxExample   [][]string    `json:"wqx_example"`  // 例句
        Entry        string        `json:"entry"`        // 词条
        Type         string        `json:"type"`         // 类型
        Related      []interface{} `json:"related"`      // 相关词汇
        Source       string        `json:"source"`       // 来源
    } `json:"dictionary"` // 词典信息
}
​
// query 函数用于向彩云小译API发送请求,查询单词的翻译和相关信息
func query(word string) {
    client := &http.Client{}
    request := DictRequest{TransType: "en2zh", Sourse: word}
    buf, err := json.Marshal(request)
    if err!= nil {
        log.Fatal(err)
    }
    var data = bytes.NewReader(buf)
    req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data)
    if err!= nil {
        log.Fatal(err)
    }
    req.Header.Set("accept", "application/json, text/plain, */*")
    req.Header.Set("accept-language", "zh")
    req.Header.Set("app-name", "xiaoyi")
    req.Header.Set("authorization", "bearer")
    req.Header.Set("content-type", "application/json;charset=UTF-8")
    req.Header.Set("device-id", "7b52fb2996701068b59c76be472b757b")
    req.Header.Set("origin", "https://fanyi.caiyunapp.com")
    req.Header.Set("os-type", "web")
    req.Header.Set("os-version", "")
    req.Header.Set("priority", "u=1, i")
    req.Header.Set("referer", "https://fanyi.caiyunapp.com/")
    req.Header.Set("sec-ch-ua", `"Chromium";v="130", "Microsoft Edge";v="130", "Not?A_Brand";v="99"`)
    req.Header.Set("sec-ch-ua-mobile", "?0")
    req.Header.Set("sec-ch-ua-platform", `"Windows"`)
    req.Header.Set("sec-fetch-dest", "empty")
    req.Header.Set("sec-fetch-mode", "cors")
    req.Header.Set("sec-fetch-site", "cross-site")
    req.Header.Set("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0")
    req.Header.Set("x-authorization", "token:qgemv4jr1y38jyq6vhvi")
    resp, err := client.Do(req)                     //发送请求到api并接受返回的响应
    if err!= nil {                                  
        log.Fatal(err)
    }
    defer resp.Body.Close()
    bodyText, err := io.ReadAll(resp.Body)
    if err!= nil {
        log.Fatal(err)
    }
​
    var dictResponse DictResponse
    err = json.Unmarshal(bodyText, &dictResponse)
    if err!= nil {
        log.Fatal(err)
    }
    //fmt.Printf("%#v\n", dictResponse)
    fmt.Println("good", "UK:", dictResponse.Dictionary.Prons.En, "US:", dictResponse.Dictionary.Prons.EnUs)
    for _, item := range dictResponse.Dictionary.Explanations {
        fmt.Println(item)
    }
​
}
​
// main 函数是程序的入口点,它解析命令行参数并调用 query 函数查询单词
func main() {
    if len(os.Args)!= 2 {
        fmt.Fprintf(os.Stderr, `usage: simpleDict WORD example: simpleDict hello`)
        os.Exit(1)
    }
    word := os.Args[1]
    query(word)
}
  1. 首先我们要从浏览器中获得我们请求头的一些参数,在使用一次翻译后找到dict包,复制其curl并用代码生成工具 (Convert curl commands to code) 直接转化成代码这样生成的代码是静态的,只支持固定的单词查询
  2. 之后我们要自己设计发送请求和接收响应的结构体,就需要用到另一个可以把json格式数据直接转换成对应的结构体的网站(JSON转Golang Struct - 在线工具 - OKTools)
  3. 完成之后,就大致可以使用了