将db变量传递给函数参数

I'm trying to parse some RSS feeds using Golang. A package I found was https://github.com/jteeuwen/go-pkg-rss

My process is

  1. Get feeds from my Postgres DB
  2. For each feed, fetch the articles
  3. Store each article into the Postgres DB

My code is as below

func main() {
  db := dbConnect() // returns the DB connection variable

  feeds := getRssFeeds(db) // returns feeds from my DB
  for i := 0; i < len(feeds); i++ {
    getFeedArticles(feeds[i].url, 5, db)
  }
}

func getFeedArticles(uri string, timeout int, db *sql.DB) {
  // using the package to get RSS feed contents
  feed := rss.New(timeout, true, chanHandler, itemHandler)
  if err := feed.Fetch(uri, nil); err != nil {
    fmt.Fprintf(os.Stderr, "[e] %s: %s", uri, err)
    return
  }
}

func chanHandler(feed *rss.Feed, newchannels []*rss.Channel) {
  // no need to do anything...
}

func itemHandler(feed *rss.Feed, ch *rss.Channel, newitems []*rss.Item) {
  for i := 0; i < len(newitems); i++ {
    fmt.Println(newitems[i].Title)

    // insert the article into DB here
  }
}

How do I pass the db variable to itemHandler so I can insert the article into my DB? I suppose I could call dbConnect() to create a new db variable to insert, but that would seem wasteful.

Is there a better way to do this process?

You can use closures:

func makeHandler(db Database) rss.ItemHandler {
    return func(feed *rss.Feed, ch *rss.Channel, newitems []*rss.Item) {
         for i := 0; i < len(newitems); i++ {
             fmt.Println(newitems[i].Title)
             // Accessed via closure:
             db.InsertArticle(newitems[i])
         }
    }
}

Or some variation thereof. You can then call rss.New with makeHandler(db), or define itemHandler in getFeedArticle... In any case, itemHandler will have db being defined and accessible.

This tutorial and this part of the specs explain it in more details