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 ausxkcdClient := client.NewXKCDClient() xkcdClient.SetTimeout(time.Duration(*clientTimeout) * time.Second)
Extra-Bonus
Mit diesem einfachen Shell-Zaubertool können Sie mehrere Comics nacheinander herunterladencomic, err := xkcdClient.Fetch(client.ComicNumber(*comicNo), *saveImage) if err != nil { log.Println(err) }
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!