流程控制 | 青训营笔记

94 阅读5分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记。 文章大部分参考Go语言中文文档。

1 流程控制

条件语句需要开发者通过指定一个或多个条件,并通过测试条件是否为 true 来决定是否执行指定语句,并在条件为 false 的情况在执行另外的语句。

Go 语言提供了以下几种条件判断语句:

1.1 if

• 可省略条件表达式括号。

• 持初始化语句,可定义代码块局部变量。

• 代码块左 括号必须在条件表达式尾部。

格式:

 if 布尔表达式 {
     /* 在布尔表达式为 true 时执行 */
 }

if 布尔表达式 {
   /* 在布尔表达式为 true 时执行 */
} else {
  /* 在布尔表达式为 false 时执行 */
}

if 布尔表达式 1 {
   /* 在布尔表达式 1 为 true 时执行 */
   if 布尔表达式 2 {
      /* 在布尔表达式 2 为 true 时执行 */
   }
}

*不支持三元操作符(三目运算符) "a > b ? a : b"。

1.2 switch

Golang switch 分支表达式可以是任意类型,不限于常量。可省略 break,默认自动终止。

switch var1 {
    case val1:
        ...
    case val2:
        ...
    default:
        ...
}

switch 语句还可以被用于 type-switch 来判断某个 interface 变量中实际存储的变量类型。

switch x.(type){
    case type:
       statement(s)      
    case type:
       statement(s)
    /* 你可以定义任意个数的case */
    default: /* 可选 */
       statement(s)
}

1.3 select

select 语句类似于 switch 语句,但是select会随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行。

select 是Go中的一个控制结构,类似于用于通信的switch语句。每个case必须是一个通信操作,要么是发送要么是接收。 select 随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行。一个默认的子句应该总是可运行的。

select {
    case communication clause  :
       statement(s);      
    case communication clause  :
       statement(s);
    /* 你可以定义任意数量的 case */
    default : /* 可选 */
       statement(s);
}

1.4 for

for init; condition; post { }
for condition { }
for { }


init: 一般为赋值表达式,给控制变量赋初值;
condition: 关系表达式或逻辑表达式,循环控制条件;
post: 一般为赋值表达式,给控制变量增量或减量。

1.5 range

Golang range类似迭代器操作,返回 (索引, 值) 或 (键, 值)。

for 循环的 range 格式可以对 slice、map、数组、字符串等进行迭代循环。格式如下:

for key, value := range oldMap {
    newMap[key] = value
}

1.6 Goto、Break、Continue

1.三个语句都可以配合标签(label)使用

2.标签名区分大小写,定以后若不使用会造成编译错误

3.continue、break配合标签(label)可用于多层循环跳出

4.goto是调整执行位置,与continue、break配合标签(label)的结果并不相同

2 案例实现

2.1 简单字典

并发实现不同翻译api下的文本翻译: 主要是实现两个不同的翻译接口。根据curl转为go简易代码,以及使用struct解码json。

package main



/*

实现了并行使用彩云和火山翻译

*/

import (

  "bytes"

  "encoding/json"

  "fmt"

  "io/ioutil"

  "log"

  "net/http"

  "os"

  "sync"

)



var wg sync.WaitGroup



type HuosanDictRequest struct {

  Language string `json:"language"`

  Text     string `json:"text"`

}



type HuosanDictResponse struct {

  Words []struct {

    Source  int    `json:"source"`

    Text    string `json:"text"`

    PosList []struct {

      Type      int `json:"type"`

      Phonetics []struct {

        Type int    `json:"type"`

        Text string `json:"text"`

      } `json:"phonetics"`

      Explanations []struct {

        Text     string `json:"text"`

        Examples []struct {

          Type      int `json:"type"`

          Sentences []struct {

            Text      string `json:"text"`

            TransText string `json:"trans_text"`

          } `json:"sentences"`

        } `json:"examples"`

        Synonyms []interface{} `json:"synonyms"`

      } `json:"explanations"`

      Relevancys []interface{} `json:"relevancys"`

    } `json:"pos_list"`

  } `json:"words"`

  Phrases  []interface{} `json:"phrases"`

  BaseResp struct {
    StatusCode    int    `json:"status_code"`
    StatusMessage string `json:"status_message"`
  } `json:"base_resp"`

}




func huosanQuery(word string) {

  defer wg.Done()

  client := &http.Client{}

  request := HuosanDictRequest{Language: "en", Text: word}

  // 编码为JSON

  buf, err := json.Marshal(request)

  if err != nil {

    log.Fatal(err)

  }

  var data = bytes.NewReader(buf)




  // var data = strings.NewReader(`{"text":"good","language":"en"}`)

  req, err := http.NewRequest("POST", "https://translate.volcengine.com/web/dict/match/v1/?msToken=&X-Bogus=DFSzswVYQDc7EOm2SWBPGTUClLy/&_signature=_02B4Z6wo00001EWhvXAAAIDBbivmtPtZ.yBFobnAAHMlaf", data)

  if err != nil {

    log.Fatal(err)

  }

  req.Header.Set("authority", "translate.volcengine.com")

  req.Header.Set("accept", "application/json, text/plain, */*")

  req.Header.Set("accept-language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")

  req.Header.Set("content-type", "application/json")

  req.Header.Set("cookie", "x-jupiter-uuid=16519125618869108; s_v_web_id=verify_9b18a50be4d814225641c5b67f7e8f77; _tea_utm_cache_2018=undefined; ttcid=741f08fe7d31434ba5ca4fb509782b6733; i18next=translate")

  req.Header.Set("origin", "https://translate.volcengine.com")

  req.Header.Set("referer", "https://translate.volcengine.com/translate?category=&home_language=zh&source_language=detect&target_language=zh&text=good")

  req.Header.Set("sec-ch-ua", `" Not A;Brand";v="99", "Chromium";v="101", "Microsoft Edge";v="101"`)

  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", "same-origin")

  req.Header.Set("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36 Edg/101.0.1210.39")

  resp, err := client.Do(req)

  if err != nil {

    log.Fatal(err)

  }

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

  }

  // fmt.Printf("%s\n", bodyText)

  var HuosanDictResponse HuosanDictResponse

  err = json.Unmarshal(bodyText, &HuosanDictResponse)

  if err != nil {

    log.Fatal(err)

  }




  fmt.Print(word + " ")

  for _, v := range HuosanDictResponse.Words {




    for i, phonetic := range v.PosList[0].Phonetics {

      if i == 0 {

        fmt.Print("UK: [", phonetic.Text+"]")

      }

      if i == 1 {

        fmt.Print(" US: [", phonetic.Text+"]")

      }

    }

    fmt.Println()

  }




  for _, v := range HuosanDictResponse.Words {

    for _, pos := range v.PosList {

      fmt.Println(pos.Explanations[0].Text)

    }




  }

  fmt.Println()

}




type XiaoyiDictRequest struct {

  TransType string `json:"trans_type"`

  Source    string `json:"source"`

  UserID    string `json:"user_id"`

}




type XiaoyiDictResponse struct {

  Rc   int `json:"rc"`

  Wiki struct {

    KnownInLaguages int `json:"known_in_laguages"`

    Description     struct {

      Source string      `json:"source"`

      Target interface{} `json:"target"`

    } `json:"description"`

    ID   string `json:"id"`

    Item struct {

      Source string `json:"source"`

      Target string `json:"target"`

    } `json:"item"`

    ImageURL  string `json:"image_url"`

    IsSubject string `json:"is_subject"`

    Sitelink  string `json:"sitelink"`

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

}




func xiaoYiQuery(word string) {

  defer wg.Done()

  client := &http.Client{}

  request := XiaoyiDictRequest{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("Connection", "keep-alive")

  req.Header.Set("DNT", "1")

  req.Header.Set("os-version", "")

  req.Header.Set("sec-ch-ua-mobile", "?0")

  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("app-name", "xy")

  req.Header.Set("Content-Type", "application/json;charset=UTF-8")

  req.Header.Set("Accept", "application/json, text/plain, */*")

  req.Header.Set("device-id", "")

  req.Header.Set("os-type", "web")

  req.Header.Set("X-Authorization", "token:qgemv4jr1y38jyq6vhvi")

  req.Header.Set("Origin", "https://fanyi.caiyunapp.com")

  req.Header.Set("Sec-Fetch-Site", "cross-site")

  req.Header.Set("Sec-Fetch-Mode", "cors")

  req.Header.Set("Sec-Fetch-Dest", "empty")

  req.Header.Set("Referer", "https://fanyi.caiyunapp.com/")

  req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9")

  req.Header.Set("Cookie", "_ym_uid=16456948721020430059; _ym_d=1645694872")

  resp, err := client.Do(req)

  if err != nil {

    log.Fatal(err)

  }

  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 XiaoyiDictResponse XiaoyiDictResponse

  err = json.Unmarshal(bodyText, &XiaoyiDictResponse)

  if err != nil {

    log.Fatal(err)

  }

  fmt.Println(word, "UK:", XiaoyiDictResponse.Dictionary.Prons.En, "US:", XiaoyiDictResponse.Dictionary.Prons.EnUs)

  for _, item := range XiaoyiDictResponse.Dictionary.Explanations {

    fmt.Println(item)

  }

  fmt.Println()

  // defer wg.Done()

}




func main() {




  if len(os.Args) < 2 {

    fmt.Fprintf(os.Stderr, `usage: simpleDict WORD

  example: simpleDict hello

      `)

    os.Exit(1)

  }




  for i := 1; i < len(os.Args); i++ {

    wg.Add(1)

    word := os.Args[i]

    go xiaoYiQuery(word)

    go huosanQuery(word)

  }

  wg.Wait()

}