英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论