go语言优势
- 高性能高并发
- 语法简单,学习曲线平缓
- 丰富的标准库
- 完善的工具链
- 静态链接
- 快速编译
- 跨平台
- 垃圾回收
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:用于将数据结构编码为格式化(缩进)JSONfunc 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)
}
- 首先我们要从浏览器中获得我们请求头的一些参数,在使用一次翻译后找到dict包,复制其curl并用代码生成工具 (Convert curl commands to code) 直接转化成代码这样生成的代码是静态的,只支持固定的单词查询
- 之后我们要自己设计发送请求和接收响应的结构体,就需要用到另一个可以把json格式数据直接转换成对应的结构体的网站(JSON转Golang Struct - 在线工具 - OKTools)
- 完成之后,就大致可以使用了