Got started with Go recently for a work project. It took a while to get used to the funky syntax and tabs for indentation instead of spaces. But, after a couple of weeks I can see totally a bunch of reasons why some people really love this relatively new language even if I am not yet ready to abandon my beloved python.
To speed up the process of getting up to speed with the new language, I decided to work on some very short projects that would still be a bit fun to stay motivated :-)
So, here we start with a simple RSS parser that returns a few fields of latest 5 episodes of a few podcasts that I follow. And here is a shoutout to two of my favourite podcasts:
- Infinite Monkey Cage by Physicst Brian Cox and comedian Robin Ince
- Dear Hank & John by John and Hank Green
Code
This is the minimal usable version of the program, which still manages to use a few cool little features of golang. Especially love that you can do things like parsing XML using just the standard library!
package main
import (
"encoding/xml"
"fmt"
"net/http"
"os"
)
// Channel struct shows how to directly access one level below top level XML element
type Channel struct {
Title string `xml:"channel>title"`
Items []Item `xml:"channel>item"`
}
// Item shows how to use a Struct from another struct
type Item struct {
Title string `xml:"title"`
Link string `xml:"link"`
Enclosure Enclosure `xml:"enclosure"`
Date string `xml:"pubDate"`
}
// Enclosure struct shows us how to view the attribute of an XML element
type Enclosure struct {
Link string `xml:"url,attr"`
}
func main() {
// golang arrays use curly braces for elements but square for identifying
// it is an array
urls := [...]string{
"https://audioboom.com/channels/4070180.rss", // Dear Hank & John
"https://audioboom.com/channels/2795952.rss", // Infinite Monkey Cage
}
// Using for loop to parse elements of list without using index
for _, url := range urls {
resp, err := http.Get(url)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
var channel Channel
if err := xml.NewDecoder(resp.Body).Decode(&channel); err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Printf("Title: %s\n", channel.Title)
fmt.Print("Items:\n")
// Here we use both index and liste items in the loop
for index, item := range channel.Items {
fmt.Printf("[%s] %s > %s\n", item.Date, item.Title, item.Enclosure.Link)
if index == 4 {
break
}
}
}
}
Next time I would love to add parallel fetching and parsing of RSS feeds using golang’s channels.