Vous avez peut-être pratiqué la syntaxe Go encore et encore, mais à moins d'avoir construit une application vous-même, vous n'avez pas ressenti la véritable sensation d'écrire une application dans Go.
.Dans cet article de blog, nous allons créer une application CLI dans Go, appelons-la go-grab-xkcd. L'application extrait les bandes dessinées de XKCD et vous les fournit via des paramètres de ligne de commande. Fournissez diverses options de fonctionnement.
Nous allons construire l'intégralité de l'application en utilisant uniquement la bibliothèque standard Go sans utiliser de dépendances externes.
L'idée de cette application peut sembler un peu idiote, mais le but est de s'entraîner à écrire au niveau de la production (en quelque sorte ) code dans Go sans chercher à se faire acquérir par Google.
Et un bonus à la fin
Remarque : Cet article suppose que le lecteur est déjà familier avec la syntaxe et la terminologie de Go, et Entre débutant et intermédiaire.
Exécutons d'abord l'application avant de continuer
$ go-grab-xkcd --help Usage of go-grab-xkcd: -n int Comic number to fetch (default latest) -o string Print output in format: text/json (default "text") -s Save image to current directory -t int Client timeout in seconds (default 30) $ go-grab-xkcd -n 323 Title: Ballmer Peak Comic No: 323 Date: 1-10-2007 Description: Apple uses automated schnapps IVs. Image: https://imgs.xkcd.com/comics/ballmer_peak.png $ go-grab-xkcd -n 323 -o json { "title": "Ballmer Peak", "number": 323, "date": "1-10-2007", "description": "Apple uses automated schnapps IVs.", "image": "https://imgs.xkcd.com/comics/ballmer_peak.png" }
Vous pouvez essayer d'autres options en téléchargeant et en exécutant l'application sur votre ordinateur.
À la fin de ceci. tutoriel, vous serez familiarisé avec les sujets suivants :
Réception des paramètres de ligne de commande
Conversion entre les structures JSON et Go
Effectuer des appels d'API
Créer des fichiers ( télécharger et enregistrer depuis le réseau)
Opérations sur les chaînes
Voici la structure du projet
$ tree go-grab-xkcd go-grab-xkcd ├── client │ └── xkcd.go └── model └── comic.go ├── main.go └── go.mod go.mod - Go Modules file used in Go for package management main.go - Main entrypoint of the application comic.go - Go representation of the data as a struct and operations on it xkcd.go - xkcd client for making HTTP calls to the API, parsing response and saving to disk
1 : Initialiser le projet
Créer un go.mod file -
$ go mod init
Cela vous aidera dans la gestion des packages (pensez aux fichiers package.json en JS).
2 : API xkcd
xkcd est incroyable et vous n'avez besoin d'aucune inscription ni clé d'accès pour utiliser leur API. Ouvrez l'API xkcd "Documentation" et vous trouverez deux points de terminaison -
http://xkcd.com/info.0.json - Obtenez les dernières bandes dessinées
http://xkcd. com/614/info.0.json - Obtenez la bande dessinée spécifiée par numéro de bande dessinée
Ce qui suit est la réponse JSON de ces points de terminaison -
{ "num": 2311, "month": "5", "day": "25", "year": "2020", "title": "Confidence Interval", "alt": "The worst part is that's the millisigma interval.", "img": "https://imgs.xkcd.com/comics/confidence_interval.png", "safe_title": "Confidence Interval", "link": "", "news": "", "transcript": "" }
Article lié à xkcd
2 : pour le modèle de création de bande dessinée
Selon la réponse JSON ci-dessus, nous créons une structure appelée ComicResponse dans comic.go dans le package modèle
type ComicResponse struct { Month string `json:"month"` Num int `json:"num"` Link string `json:"link"` Year string `json:"year"` News string `json:"news"` SafeTitle string `json:"safe_title"` Transcript string `json:"transcript"` Alt string `json:"alt"` Img string `json:"img"` Title string `json:"title"` Day string `json:"day"` }
Vous pouvez utiliser l'outil JSON-to-Go pour générez-le automatiquement à partir de la structure JSON.
Au fait, créez une autre structure qui sera utilisée pour sortir les données de notre application.
type Comic struct { Title string `json:"title"` Number int `json:"number"` Date string `json:"date"` Description string `json:"description"` Image string `json:"image"` }
Ajoutez les deux méthodes suivantes à la structure ComicResponse
// FormattedDate 函数将格式化日期元素为一个字符串 func (cr ComicResponse) FormattedDate() string { return fmt.Sprintf("%s-%s-%s", cr.Day, cr.Month, cr.Year) } // Comic 函数将从 API 接收到的 ComicResponse 转换为应用程序的输出格式, Comic 结构体 func (cr ComicResponse) Comic() Comic { return Comic{ Title: cr.Title, Number: cr.Num, Date: cr.FormattedDate(), Description: cr.Alt, Image: cr.Img, } }
Ajoutez ensuite les deux méthodes suivantes à la structure Comic
// PrettyString 函数创建一个漂亮的 Comic 字符串并用于输出 func (c Comic) PrettyString() string { p := fmt.Sprintf( "Title: %s\nComic No: %d\nDate: %s\nDescription: %s\nImage: %s\n", c.Title, c.Number, c.Date, c.Description, c.Image) return p } // JSON 函数将 Comic 结构体转换为 JSON, 我们将使用 JSON 字符串作为输出内容 func (c Comic) JSON() string { cJSON, err := json.Marshal(c) if err != nil { return "" } return string(cJSON) }
3 : Configurez le client xkcd pour lancer une requête, analysez la réponse et enregistrez-la sur le disque
Créez xkcd dans le package client. go file.
Définissez d’abord un type personnalisé appelé ComicNumber, le type de données est int
tapez ComicNumber int
Définissez des constantes
const ( // xkcd 的 BaseURL BaseURL string = "https://xkcd.com" // DefaultClientTimeout 是取消请求之前要等待的时间 DefaultClientTimeout time.Duration = 30 * time.Second // 根据 xkcd API, LatestComic 是最新的漫画编号 LatestComic ComicNumber = 0 )
Créer une structure XKCDClient, qui servira à faire des requêtes à l'API.
// XKCDClient 是 XKCD 的客户端结构体 type XKCDClient struct { client *http.Client baseURL string } // NewXKCDClient 创建一个新的 XKCDClient func NewXKCDClient() *XKCDClient { return &XKCDClient{ client: &http.Client{ Timeout: DefaultClientTimeout, }, baseURL: BaseURL, } }
Ajoutez les 4 méthodes suivantes à XKCDClient
SetTimeout()
// SetTimeout 重写了默认的 ClientTimeout func (hc *XKCDClient) SetTimeout(d time.Duration) { hc.client.Timeout = d }
Fetch()
// Fetch 根据提供的漫画编号检索漫画 func (hc *XKCDClient) Fetch(n ComicNumber, save bool) (model.Comic, error) { resp, err := hc.client.Get(hc.buildURL(n)) if err != nil { return model.Comic{}, err } defer resp.Body.Close() var comicResp model.ComicResponse if err := json.NewDecoder(resp.Body).Decode(&comicResp); err != nil { return model.Comic{}, err } if save { if err := hc.SaveToDisk(comicResp.Img, "."); err != nil { fmt.Println("Failed to save image!") } } return comicResp.Comic(), nil }
SaveToDisk()
// SaveToDisk 下载并保存漫画到本地磁盘 func (hc *XKCDClient) SaveToDisk(url, savePath string) error { resp, err := http.Get(url) if err != nil { return err } defer resp.Body.Close() absSavePath, _ := filepath.Abs(savePath) filePath := fmt.Sprintf("%s/%s", absSavePath, path.Base(url)) file, err := os.Create(filePath) if err != nil { return err } defer file.Close() _, err = io.Copy(file, resp.Body) if err != nil { return err } return nil }
buildURL()
func (hc *XKCDClient) buildURL(n ComicNumber) string { var finalURL string if n == LatestComic { finalURL = fmt.Sprintf("%s/info.0.json", hc.baseURL) } else { finalURL = fmt.Sprintf("%s/%d/info.0.json", hc.baseURL, n) } return finalURL }
4 : Connectez tout
Dans la fonction main(), nous lions tout le contenu
lire les paramètres de ligne de commande
Instancier XKCDClient
Utiliser XKCDClient pour extraire les données de l'API
Sortie
Lire les paramètres de ligne de commande
comicNo := flag.Int( "n", int(client.LatestComic), "Comic number to fetch (default latest)", ) clientTimeout := flag.Int64( "t", int64(client.DefaultClientTimeout.Seconds()), "Client timeout in seconds", ) saveImage := flag.Bool( "s", false, "Save image to current directory", ) outputType := flag.String( "o", "text", "Print output in format: text/json", )
flag.Parse()
instancier
Ou construisez-le en tant qu'exécutable binaire sur votre ordinateur portable et exécutez-lexkcdClient := client.NewXKCDClient() xkcdClient.SetTimeout(time.Duration(*clientTimeout) * time.Second)
Bonus supplémentaire
Vous pouvez télécharger plusieurs bandes dessinées en séquence en utilisant cet outil magique de shell simplecomic, err := xkcdClient.Fetch(client.ComicNumber(*comicNo), *saveImage) if err != nil { log.Println(err) }
Tutoriels recommandés : "PHP
" "Aller au didacticiel
"Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!