Heim  >  Artikel  >  Backend-Entwicklung  >  Erstellen Sie ein CLI-Programm mit Go

Erstellen Sie ein CLI-Programm mit Go

Guanhui
Guanhuinach vorne
2020-06-12 18:28:173601Durchsuche

Erstellen Sie ein CLI-Programm mit Go

Sie haben vielleicht immer wieder die Go-Syntax geübt, aber wenn Sie nicht selbst eine Anwendung erstellt haben, haben Sie noch nicht das wirkliche Gefühl erlebt, Anwendungen in Go zu schreiben.

In diesem Blog-Beitrag erstellen wir eine CLI-Anwendung in Go, nennen wir sie go-grab-xkcd. Die Anwendung ruft Comics von XKCD ab und stellt sie über Befehlszeilenparameter für Sie bereit.

Wir werden die gesamte Anwendung nur unter Verwendung der Go-Standardbibliothek erstellen, ohne externe Abhängigkeiten zu verwenden.

Die Idee dieser Anwendung mag etwas albern erscheinen, aber der Zweck besteht darin, das Schreiben von Code (sozusagen) auf Produktionsebene zu üben in Go, ohne zu versuchen, von Google erfasst zu werden.

Am Ende gibt es einen Bonus

Hinweis: In diesem Artikel wird davon ausgegangen, dass der Leser bereits mit der Syntax und Terminologie von Go sowie zwischen Anfänger und Fortgeschrittenen vertraut ist .

Lass uns zuerst die App ausführen, bevor wir fortfahren

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

Sie können andere Optionen ausprobieren, indem Sie die App herunterladen und auf Ihrem Computer ausführen.

Am Ende dieses Tutorials sind Sie wird mit den folgenden Themen vertraut sein:

Befehlszeilenparameter empfangen

Konvertieren zwischen JSON- und Go-Strukturen

API-Aufrufe durchführen

Dateien erstellen (herunterladen und aus dem Netzwerk speichern)

String-Operationen

Das Folgende ist die Projektstruktur

$ 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: Initialisieren Sie das Projekt

Erstellen Sie eine go.mod-Datei -

$ go mod init

Dies hilft Ihnen bei der Paketverwaltung (denken Sie an package.json-Dateien in JS).

2: xkcd-API

xkcd ist fantastisch und Sie benötigen keine Registrierung oder Zugriffsschlüssel, um ihre API zu verwenden. Öffnen Sie die xkcd-API „Dokumentation“ und Sie finden zwei Endpunkte –

http://xkcd.com/info.0.json – Holen Sie sich die neuesten Comics

http://xkcd. com/614/info.0.json – Erhalten Sie den angegebenen Comic nach Comic-Nummer

Das Folgende ist die JSON-Antwort für diese Endpunkte –

{
  "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": ""
}

Artikelbezogener xkcd

2 : für Comic-Erstellungsmodell

Gemäß der obigen JSON-Antwort erstellen wir eine Struktur namens ComicResponse in comic.go im Modellpaket

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

Sie können dazu das JSON-to-Go-Tool verwenden Generieren Sie es automatisch aus der JSON-Struktur.

Erstellen Sie übrigens eine weitere Struktur, die zur Ausgabe von Daten aus unserer Anwendung verwendet wird.

type Comic struct {
    Title       string `json:"title"`
    Number      int    `json:"number"`
    Date        string `json:"date"`
    Description string `json:"description"`
    Image       string `json:"image"`
}

Fügen Sie die folgenden zwei Methoden zur ComicResponse-Struktur hinzu

// 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,
    }
}

Fügen Sie dann die folgenden zwei Methoden zur Comic-Struktur hinzu

// 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: Richten Sie den xkcd-Client so ein, dass er eine Anfrage initiiert, die Antwort analysiert und auf der Festplatte speichert

Erstellen Sie xkcd im Client-Paket. go-Datei.

Definieren Sie zunächst einen benutzerdefinierten Typ namens ComicNumber, der Datentyp ist int

Typ ComicNumber int

Konstanten definieren

const (
    // xkcd 的 BaseURL
    BaseURL string = "https://xkcd.com"
    // DefaultClientTimeout 是取消请求之前要等待的时间
    DefaultClientTimeout time.Duration = 30 * time.Second
    // 根据 xkcd API, LatestComic 是最新的漫画编号
    LatestComic ComicNumber = 0
)

Erstellen eine Struktur XKCDClient, die verwendet wird, um Anfragen an die API zu stellen.

// XKCDClient 是 XKCD 的客户端结构体
type XKCDClient struct {
    client  *http.Client
    baseURL string
}
// NewXKCDClient 创建一个新的 XKCDClient
func NewXKCDClient() *XKCDClient {
    return &XKCDClient{
        client: &http.Client{
            Timeout: DefaultClientTimeout,
        },
        baseURL: BaseURL,
    }
}

Fügen Sie die folgenden 4 Methoden zu XKCDClient hinzu

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: Alle verbinden

Innerhalb der main()-Funktion verlinken wir alle Inhalte

Befehlszeilenparameter lesen

XKCDClient instanziieren

XKCDClient verwenden, um Daten von der API abzurufen

Ausgabe

Befehlszeilenparameter lesen

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

instanziieren

Oder erstellen Sie es als binäre ausführbare Datei auf Ihrem Laptop und führen Sie es aus

xkcdClient := client.NewXKCDClient()
xkcdClient.SetTimeout(time.Duration(*clientTimeout) * time.Second)

Der vollständige Quellcode finden Sie in diesem Github-Repo – go-grab- xkcd

Extra-Bonus

Mit diesem einfachen Shell-Zaubertool können Sie mehrere Comics nacheinander herunterladen

comic, err := xkcdClient.Fetch(client.ComicNumber(*comicNo), *saveImage)
if err != nil {
    log.Println(err)
}

Der obige Shell-Code ruft einfach go- auf. grab-xkcd in einem for-Schleifenbefehl, da xkcd Sequenz-Ganzzahlen verwendet, ersetzen Sie den i-Wert durch die Comic-Nummer als Comic-Nummer/ID.

Empfohlene Tutorials: "PHP

" "

Go Tutorial

"

Das obige ist der detaillierte Inhalt vonErstellen Sie ein CLI-Programm mit Go. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:learnku.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen
Vorheriger Artikel:Gehen Sie zum String-ParsenNächster Artikel:Gehen Sie zum String-Parsen