Maison > développement back-end > Golang > le corps du texte

Créer un programme CLI à l'aide de Go

Guanhui
Libérer: 2020-06-13 09:03:28
avant
3583 Les gens l'ont consulté

Créer un programme CLI à l'aide de Go

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"
}
Copier après la connexion

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
Copier après la connexion

1 : Initialiser le projet

Créer un go.mod file -

$ go mod init
Copier après la connexion

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": ""
}
Copier après la connexion

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"`
}
Copier après la connexion

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"`
}
Copier après la connexion

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,
    }
}
Copier après la connexion

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)
}
Copier après la connexion

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
)
Copier après la connexion

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,
    }
}
Copier après la connexion

Ajoutez les 4 méthodes suivantes à XKCDClient

SetTimeout()

// SetTimeout 重写了默认的 ClientTimeout
func (hc *XKCDClient) SetTimeout(d time.Duration) {
    hc.client.Timeout = d
}
Copier après la connexion

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
}
Copier après la connexion

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
}
Copier après la connexion

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
}
Copier après la connexion

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",
)
Copier après la connexion

flag.Parse()

instancier

Ou construisez-le en tant qu'exécutable binaire sur votre ordinateur portable et exécutez-le

xkcdClient := client.NewXKCDClient()
xkcdClient.SetTimeout(time.Duration(*clientTimeout) * time.Second)
Copier après la connexion

Le code source complet peut être trouvé dans ce dépôt Github - allez-y -xkcd

Bonus supplémentaire

Vous pouvez télécharger plusieurs bandes dessinées en séquence en utilisant cet outil magique de shell simple

comic, err := xkcdClient.Fetch(client.ComicNumber(*comicNo), *saveImage)
if err != nil {
    log.Println(err)
}
Copier après la connexion
Le code shell ci-dessus appelle simplement go -grab-xkcd dans une commande de boucle for, puisque xkcd utilise des entiers de séquence, remplacez la valeur i par le numéro de bande dessinée comme numéro/ID de bande dessinée.

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!

Étiquettes associées:
source:learnku.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!