Go语言的实战案例二 | 青训营笔记

62 阅读2分钟

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

demo2. SimpleDict

code: go-by-example/main.go at master · wangkechun/go-by-example (github.com)


type DictRequest struct {
	TransType string `json:"trans_type"`
	Source    string `json:"source"`
	UserID    string `json:"user_id"`
}

type DictResponse struct {
	...
}

func query(word string) {
	client := &http.Client{}
	request := DictRequest{TransType: "en2zh", Source: 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("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36")
	req.Header.Set("Content-Type", "application/json;charset=UTF-8")
	req.Header.Set("Accept", "application/json, text/plain, */*")
	
        ...
        
	defer resp.Body.Close()
	bodyText, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	if resp.StatusCode != 200 {
		log.Fatal("bad StatusCode:", resp.StatusCode, "body", string(bodyText))
	}
	var dictResponse DictResponse
	err = json.Unmarshal(bodyText, &dictResponse)
	if err != nil {
		log.Fatal(err)
	}
}

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. os.Args

  1. 获取命令行参数
    os.Args  // Args包含命令行参数,从程序名开始。
    
    注意:os.Args 第一个参数, 即 os.Args[0] 存放的是参数个数。

2. http

  1. 初始化 Client 服务
    client := &http.Client{ }  // 初始化一个 http.Client 服务
    
  2. 生成 Http 请求
    req,err := http.NewRequest(ethod, url string, body io.Reader)  
    // 实际调用:NewRequestWithContext(context.Background(), method, url, body)
    // NewRequest使用context.Background包装NewRequestWithContext。
    // NewRequestWithContext返回给定方法、URL和可选 body 的新请求。
    
  3. 设置 Http 请求
    req.Header.Set()  // Set将与键关联的标题项设置为单个元素值。
    
    // example
    req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36")
    req.Header.Set("Content-Type", "application/json;charset=UTF-8")
    req.Header.Set("Accept", "application/json, text/plain, */*")
    
  4. 发起 Http 请求
    resp, err := client.Do(req)  // Do发送HTTP请求并返回HTTP响应,遵循客户端上配置的策略(如重定向、cookie、身份验证)。
    // 通常使用Get、Post或PostForm来代替Do。
    
  5. 关闭 Http 连接
    resp.Body.Close() 
    

3. Tag

type DictRequest struct {
	TransType string `json:"trans_type"`
	Source string `json:"source"`
	UserID string `json:"user_id"`
}
  1. 使用一对 `` 定义一个 tag
    `json:"tag"`  // 定义一个 JSON Tag
    
  2. 该结构体定义一个 JSON 数据为:
    {
    	"trans_type": "string",
    	"source": "string",
    	"user_id": "string"
    }
    

4. json

  1. json.Marshal

    json.Marshal(request)  // Marshal返回 JSON 编码
    // bool 编码为 JSON 布尔值。
    // float, int 编码为 JSON 数字。
    // string 编码为有效的 UTF-8 的 JSON 字符串,
    // 用 Unicode 替换符文替换 rune。
    

    注意的是: 为了使JSON能够安全地嵌入 HTML<script> 标记中,字符串使用HTMLEscape 进行编码,它替换了 “<”、“>”、“&”、U+2028U+2029。字符串被转义为 “\u003c”、“\u003e”、“\u0026”、“u2028”“\u2029”。使用编码器时,可以通过调用 SetEscapeHTML(false) 禁用此替换。

  2. json.Unmarshal

    json.Unmarshal(bodyText, &dictResponse)  // func Unmarshal(data []byte, v any) error { }
    
    // bool, for JSON booleans  
    // float64, for JSON numbers  
    // string, for JSON strings  
    // []interface{}, for JSON arrays  
    // map[string]interface{}, for JSON objects  
    // nil for JSON null
    

    注意的是: Unmarshal 解析 JSON 编码的数据并将结果存储在 v 指向的值中。如果v为nil或不是指针,Unmarshall 将返回 Error。

5. io

  1. NewReader

    bytes.NewReader(buf)  // func NewReader(b []byte) *Reader { return &Reader{b, 0, -1} }
    // NewReader从 b 返回新的 Reader。
    

    Reader 过读取字节切片实现 io.Readerio.ReaderAtio.WriterToio.Seekerio.ByteScannerio.RuneScanner 接口。

    Buffer 不同,Reader 是只读的。

  2. ReadAll

ioutil.ReadAll(resp.Body)  // ReadAll reads from r until an error or EOF and returns the data it read.
// 从Go1.16开始,此函数为 io.ReadAll。