之前曾经写过一篇go语言基础文章,但是尚未完成项目实践,只学习了基础知识。现在参加了第六届青训营,也因此将之前的笔记重新整理,正好是暑假,可以更认真的整理技术框架、学习新知识、增长项目经验。
猜谜游戏
涉及知识点:随机数种子
在Golang中,随机数生成器是基于一个种子(seed)生成的。种子是一个整数值,它用于初始化随机数生成器的状态。如果两个随机数生成器的种子相同,它们就会生成相同的随机数序列。
在这个猜数字游戏的例子中,我们使用了time包中的UnixNano()函数来获取当前时间的纳秒数作为种子,以保证每次运行程序生成的随机数都是不同的。如果我们没有使用种子或者使用了相同的种子,那么每次运行程序生成的随机数序列都会相同,这样就无法保证游戏的随机性和公正性。
具体来说,我们使用了rand包中的Seed()函数来将当前时间的纳秒数作为种子,并将其传递给rand.Intn()函数,以生成一个1到100之间的随机整数。Seed()函数只需要在程序运行时调用一次即可,因为它会将种子保存到随机数生成器的状态中,随后的随机数生成都会基于这个种子。
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
// 生成一个1到100之间的随机整数
rand.Seed(time.Now().UnixNano())
secretNumber := rand.Intn(100) + 1
// 控制台输出欢迎信息
fmt.Println("欢迎来到猜数字游戏!")
fmt.Println("请猜一个1到100之间的整数。")
// 循环获取用户输入,直到猜中为止
var guess int
for {
fmt.Print("你的猜测是:")
fmt.Scan(&guess)
if guess < secretNumber {
fmt.Println("太小了!再试一次。")
} else if guess > secretNumber {
fmt.Println("太大了!再试一次。")
} else {
fmt.Println("恭喜你猜中了!")
break
}
}
}
在线词典
涉及知识点:api调用,http服务,json序列化,解析response body,代码生成
第一步:请求代码生成
我在这里调用了百度翻译的api,使用教程提供的Convert curl to Go (curlconverter.com)进行了代码生成,得到代码如下:
package main
import (
"fmt"
"io"
"log"
"net/http"
"strings"
)
func main() {
client := &http.Client{}
var data = strings.NewReader(`from=en&to=zh&query=hello&transtype=realtime&simple_means_flag=3&sign=54706.276099&token=c4cd174dca1ef9d313024df75cf74d42&domain=common&ts=1690296997065`)
req, err := http.NewRequest("POST", "https://fanyi.baidu.com/v2transapi?from=en&to=zh", data)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Accept", "*/*")
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("Acs-Token", "1690296988794_1690296997094_/oJqs0ycj8r8vPlZquYwo9HOqn/dnoyTnUz3MwAbF9Tb1QJd/DNzadYqVZMA9mLn9kqyLBVAOdUEBkhyIXDkfYdJHbPYkb/0A7UfQhSR4F4ZFMmvsb6NURwEMgV8C2wwJDkvBuzNs/2KzhOVLFFyXsx61aSGO3DOF8ayUoBTY8ugp9PDe8pCbnWoaQwEoRLnBTtCnZskVGzbCCRvK93pko5BnIgVeLAQpUL4MDXA1mmvcVbmexlPMMlCewWL5pmw2sP2VIj1oI9YFrUs6TlivN17IJgWyL3tjd+GoO1UTAlB2LItuSBRyO4eRpoQov6dVuZ8LAIQP9iJi8u/xtMXmDO6/qyvW4GxbMK6VA/mb3ZBFPyo5NWomd9eEFVVpB9hsUs6qyYkVKH220znwfn/7wf96gokvTWAo0YZKJ767jp43DKDdYH3aqvi09Uild4ftUTNXU66cYqA7744E2IJrQS+NEQM9oonotrDFf0hjp13Nss0Tiagxrg1Wp8O05tj3HLCYTijBjnB5/coyGvULw==")
req.Header.Set("Connection", "keep-alive")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
req.Header.Set("Cookie", "BIDUPSID=E54970232927D08BF091EB133681C737; PSTM=1683706717; BAIDUID=E54970232927D08B468F87308B610090:FG=1; BAIDUID_BFESS=E54970232927D08B468F87308B610090:FG=1; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; H_PS_PSSID=26350; ab_sr=1.0.1_MzJiMDg1ZGJhNDZlNWRkMzZlNGM1N2FlZGEyOWEwZGRhMjU1NzA1NWI3YmFmMDBlNGJiY2I1ZTU5OWMyOWNhNzkyY2Q3NWE0ZTg0YTdlMTcxYzllZDU1ZTAyM2Y4ZWU2MDMyZjE5NjY4MDgxYjM0ODNiZmFlZDk0MTQzNmNmNmY3MjcxMTJlMTI1MjE1NzkzYzA1NjkyMmRiZWZhNWE0OQ==")
req.Header.Set("Origin", "https://fanyi.baidu.com")
req.Header.Set("Referer", "https://fanyi.baidu.com/?aldtype=16047")
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/115.0.0.0 Safari/537.36 Edg/115.0.1901.183")
req.Header.Set("X-Requested-With", "XMLHttpRequest")
req.Header.Set("sec-ch-ua", `"Not/A)Brand";v="99", "Microsoft Edge";v="115", "Chromium";v="115"`)
req.Header.Set("sec-ch-ua-mobile", "?0")
req.Header.Set("sec-ch-ua-platform", `"Windows"`)
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", bodyText)
}
得到了JSON:
第二步:基础调用逻辑
搭建一个基础的服务器用于作为中介
package main
import (
"fmt"
"net/http"
"log"
"encoding/json"
)
type Definition struct {
Definition string `json:"definition"`
}
func main() {
http.HandleFunc("/", handleIndex)
http.HandleFunc("/define", handleDefine)
fmt.Println("Listening on :3000")
http.ListenAndServe(":3000", nil)
}
func handleIndex(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Welcome to the online dictionary!")
}
func handleDefine(w http.ResponseWriter, r *http.Request) {
word := r.URL.Query().Get("word")
if word == "" {
http.Error(w, "Please provide a word to define", http.StatusBadRequest)
return
}
resp, err := http.Get("https://api.dictionaryapi.dev/api/v2/entries/en/" + word)
if err != nil {
http.Error(w, "Failed to retrieve definition", http.StatusInternalServerError)
return
}
defer resp.Body.Close()
var definitions []Definition
err = json.NewDecoder(resp.Body).Decode(&definitions)
if err != nil {
http.Error(w, "Failed to decode definition", http.StatusInternalServerError)
return
}
if len(definitions) == 0 {
fmt.Fprintf(w, "No definition found for %s", word)
return
}
fmt.Fprintf(w, "%s: %s", word, definitions[0].Definition)
}
第三步:完善以及完成代码
由于百度云api对开发者要求比较严格,我的代码中的token与sign部分只是从浏览器截取,无法完成比较完善的功能,以下代码仅供参考
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"time"
)
type DictRequest struct {
From string `url:"from"`
To string `url:"to"`
Query string `url:"query"`
TransType string `url:"transtype"`
SimpleMeansFlag int `url:"simple_means_flag"`
Sign string `url:"sign"`
Token string `url:"token"`
Domain string `url:"domain"`
Timestamp int64 `url:"ts"`
}
type DictResponse struct {
TransResult struct {
Data []struct {
Dst string `json:"dst"`
Src string `json:"src"`
} `json:"data"`
From string `json:"from"`
To string `json:"to"`
Status int `json:"status"`
Type int `json:"type"`
Phonetic []struct {
SrcStr string `json:"src_str"`
TrgStr string `json:"trg_str"`
} `json:"phonetic"`
} `json:"trans_result"`
DictResult struct {
Edict struct {
Item []struct {
TrGroup []struct {
Tr []string `json:"tr"`
Example []string `json:"example"`
SimilarWord []string `json:"similar_word"`
} `json:"tr_group"`
Pos string `json:"pos"`
} `json:"item"`
Word string `json:"word"`
} `json:"edict"`
From string `json:"from"`
SimpleMeans struct {
WordName string `json:"word_name"`
From string `json:"from"`
WordMeans []string `json:"word_means"`
Tags struct {
Core []string `json:"core"`
Other []string `json:"other"`
} `json:"tags"`
Exchange struct {
WordPl []string `json:"word_pl"`
} `json:"exchange"`
Symbols []struct {
PhEn string `json:"ph_en"`
PhAm string `json:"ph_am"`
Parts []struct {
Part string `json:"part"`
Means []string `json:"means"`
} `json:"parts"`
PhOther string `json:"ph_other"`
} `json:"symbols"`
} `json:"simple_means"`
Common struct {
Text string `json:"text"`
} `json:"common"`
Collins struct {
Entry []struct {
Type string `json:"type"`
EntryID string `json:"entry_id"`
Value []struct {
MeanType []struct {
InfoType string `json:"info_type"`
InfoID string `json:"info_id"`
Example []struct {
ExampleID string `json:"example_id"`
TtsSize string `json:"tts_size"`
Tran string `json:"tran"`
Ex string `json:"ex"`
TtsMp3 string `json:"tts_mp3"`
} `json:"example,omitempty"`
Posc []struct {
Tran string `json:"tran"`
PoscID string `json:"posc_id"`
Example []struct {
ExampleID string `json:"example_id"`
Tran string `json:"tran"`
Ex string `json:"ex"`
TtsMp3 string `json:"tts_mp3"`
} `json:"example"`
Def string `json:"def"`
} `json:"posc,omitempty"`
} `json:"mean_type"`
Gramarinfo []struct {
Tran string `json:"tran"`
Type string `json:"type"`
Label string `json:"label"`
} `json:"gramarinfo"`
Tran string `json:"tran"`
Def string `json:"def"`
MeanID string `json:"mean_id"`
Posp []struct {
Label string `json:"label"`
} `json:"posp"`
} `json:"value"`
} `json:"entry"`
WordName string `json:"word_name"`
WordID string `json:"word_id"`
WordEmphasize string `json:"word_emphasize"`
Frequence string `json:"frequence"`
} `json:"collins"`
Lang string `json:"lang"`
Oxford struct {
Entry []struct {
Tag string `json:"tag"`
Name string `json:"name"`
Data []struct {
Tag string `json:"tag"`
Data []struct {
Tag string `json:"tag"`
Data []struct {
Tag string `json:"tag"`
Data []struct {
Tag string `json:"tag"`
Data []struct {
Tag string `json:"tag"`
EnText string `json:"enText,omitempty"`
ChText string `json:"chText,omitempty"`
G string `json:"g,omitempty"`
Data []struct {
Text string `json:"text"`
HoverText string `json:"hoverText"`
} `json:"data,omitempty"`
} `json:"data"`
} `json:"data"`
} `json:"data,omitempty"`
P string `json:"p,omitempty"`
PText string `json:"p_text,omitempty"`
N string `json:"n,omitempty"`
Xt string `json:"xt,omitempty"`
} `json:"data"`
} `json:"data"`
} `json:"entry"`
Unbox []struct {
Tag string `json:"tag"`
Type string `json:"type"`
Name string `json:"name"`
Data []struct {
Tag string `json:"tag"`
Text string `json:"text,omitempty"`
Words string `json:"words,omitempty"`
Outdent string `json:"outdent,omitempty"`
Data []struct {
Tag string `json:"tag"`
EnText string `json:"enText"`
ChText string `json:"chText"`
} `json:"data,omitempty"`
} `json:"data"`
} `json:"unbox"`
} `json:"oxford"`
BaiduPhrase []struct {
Tit []string `json:"tit"`
Trans []string `json:"trans"`
} `json:"baidu_phrase"`
Sanyms []struct {
Tit string `json:"tit"`
Type string `json:"type"`
Data []struct {
P string `json:"p"`
D []string `json:"d"`
} `json:"data"`
} `json:"sanyms"`
QueryExplainVideo struct {
ID int `json:"id"`
UserID string `json:"user_id"`
UserName string `json:"user_name"`
UserPic string `json:"user_pic"`
Query string `json:"query"`
Direction string `json:"direction"`
Type string `json:"type"`
Tag string `json:"tag"`
Detail string `json:"detail"`
Status string `json:"status"`
SearchType string `json:"search_type"`
FeedURL string `json:"feed_url"`
Likes string `json:"likes"`
Plays string `json:"plays"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
DuplicateID string `json:"duplicate_id"`
RejectReason string `json:"reject_reason"`
CoverURL string `json:"coverUrl"`
VideoURL string `json:"videoUrl"`
ThumbURL string `json:"thumbUrl"`
VideoTime string `json:"videoTime"`
VideoType string `json:"videoType"`
} `json:"queryExplainVideo"`
} `json:"dict_result"`
LijuResult struct {
Double string `json:"double"`
Tag []string `json:"tag"`
Single string `json:"single"`
} `json:"liju_result"`
Logid int64 `json:"logid"`
}
func main() {
client := &http.Client{}
request := DictRequest{
From: "en",
To: "zh",
Query: "hello",
TransType: "trans",
SimpleMeansFlag: 3,
Sign: "54706.276099",
Token: "c4cd174dca1ef9d313024df75cf74d42",
Domain: "common",
Timestamp: time.Now().Unix(),
}
buf, err := json.Marshal(request)
if err != nil {
log.Fatal(err)
}
var data = bytes.NewReader(buf)
req, err := http.NewRequest("POST", "https://fanyi.baidu.com/v2transapi?from=en&to=zh", data)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Accept", "*/*")
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("Acs-Token", "1690296988794_1690296997094_/oJqs0ycj8r8vPlZquYwo9HOqn/dnoyTnUz3MwAbF9Tb1QJd/DNzadYqVZMA9mLn9kqyLBVAOdUEBkhyIXDkfYdJHbPYkb/0A7UfQhSR4F4ZFMmvsb6NURwEMgV8C2wwJDkvBuzNs/2KzhOVLFFyXsx61aSGO3DOF8ayUoBTY8ugp9PDe8pCbnWoaQwEoRLnBTtCnZskVGzbCCRvK93pko5BnIgVeLAQpUL4MDXA1mmvcVbmexlPMMlCewWL5pmw2sP2VIj1oI9YFrUs6TlivN17IJgWyL3tjd+GoO1UTAlB2LItuSBRyO4eRpoQov6dVuZ8LAIQP9iJi8u/xtMXmDO6/qyvW4GxbMK6VA/mb3ZBFPyo5NWomd9eEFVVpB9hsUs6qyYkVKH220znwfn/7wf96gokvTWAo0YZKJ767jp43DKDdYH3aqvi09Uild4ftUTNXU66cYqA7744E2IJrQS+NEQM9oonotrDFf0hjp13Nss0Tiagxrg1Wp8O05tj3HLCYTijBjnB5/coyGvULw==")
req.Header.Set("Connection", "keep-alive")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
req.Header.Set("Cookie", "BIDUPSID=E54970232927D08BF091EB133681C737; PSTM=1683706717; BAIDUID=E54970232927D08B468F87308B610090:FG=1; BAIDUID_BFESS=E54970232927D08B468F87308B610090:FG=1; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; H_PS_PSSID=26350; ab_sr=1.0.1_MzJiMDg1ZGJhNDZlNWRkMzZlNGM1N2FlZGEyOWEwZGRhMjU1NzA1NWI3YmFmMDBlNGJiY2I1ZTU5OWMyOWNhNzkyY2Q3NWE0ZTg0YTdlMTcxYzllZDU1ZTAyM2Y4ZWU2MDMyZjE5NjY4MDgxYjM0ODNiZmFlZDk0MTQzNmNmNmY3MjcxMTJlMTI1MjE1NzkzYzA1NjkyMmRiZWZhNWE0OQ==")
req.Header.Set("Origin", "https://fanyi.baidu.com")
req.Header.Set("Referer", "https://fanyi.baidu.com/?aldtype=16047")
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/115.0.0.0 Safari/537.36 Edg/115.0.1901.183")
req.Header.Set("X-Requested-With", "XMLHttpRequest")
req.Header.Set("sec-ch-ua", `"Not/A)Brand";v="99", "Microsoft Edge";v="115", "Chromium";v="115"`)
req.Header.Set("sec-ch-ua-mobile", "?0")
req.Header.Set("sec-ch-ua-platform", `"Windows"`)
resp, err := client.Do(req)
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.Print("%#v\n", dictResponse)
}