英文:
Pass db variable to function argument
问题
我正在尝试使用Golang解析一些RSS源。我找到了一个包:https://github.com/jteeuwen/go-pkg-rss
我的流程如下:
- 从我的Postgres数据库获取源
- 对于每个源,获取文章
- 将每篇文章存储到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
- Get feeds from my Postgres DB
- For each feed, fetch the articles
- 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?
答案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 < 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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论