将db变量传递给函数参数

huangapple go评论74阅读模式
英文:

Pass db variable to function argument

问题

我正在尝试使用Golang解析一些RSS源。我找到了一个包:https://github.com/jteeuwen/go-pkg-rss

我的流程如下:

  1. 从我的Postgres数据库获取源
  2. 对于每个源,获取文章
  3. 将每篇文章存储到Postgres数据库中

我的代码如下:

func main() {
  db := dbConnect() // 返回数据库连接变量
  
  feeds := getRssFeeds(db) // 从数据库中获取源
  for i := 0; i < len(feeds); i++ {
    getFeedArticles(feeds[i].url, 5, db)
  }
}

func getFeedArticles(uri string, timeout int, db *sql.DB) {
  // 使用该包获取RSS源内容
  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) {
  // 不需要做任何操作...
}

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

    // 在这里将文章插入到数据库中
  }
}

如何将db变量传递给itemHandler,以便我可以将文章插入到我的数据库中?我想我可以调用dbConnect()来创建一个新的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 &lt; 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, &quot;[e] %s: %s&quot;, 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 &lt; 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?

答案1

得分: 3

你可以使用闭包:

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)
            // 通过闭包访问:
            db.InsertArticle(newitems[i])
        }
    }
}

或者其他变体。然后你可以使用 makeHandler(db) 调用 rss.New,或者在 getFeedArticle 中定义 itemHandler... 无论哪种情况,itemHandler 都会有 db 被定义和可访问。

这个教程规范的这一部分 对此进行了更详细的解释。

英文:

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 &lt; 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

huangapple
  • 本文由 发表于 2014年1月7日 14:37:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/20965401.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定