所以我正在尝试使用Rob Pike的fanin函数编写一个webcrawler。
这是我的代码 -
package main
import (
"net/http"
"encoding/json"
"fmt"
"io/ioutil"
)
func main() {
fanIn(getDuckDuckGo("food"), getGitHub("defunkt"))
}
type DuckDuckGoResponse struct {
RelatedTopics []struct {
Result string `json:"Result"`
FirstUrl string `json:"FirstURL"`
Text string `json:"Text"`
} `json:"RelatedTopics"`
}
type GitHubResponse struct {
Login string `json:"login"`
Email string `json:"email"`
Name string `json:"name"`
}
func fanIn(input1 <-chan DuckDuckGoResponse, input2 <-chan GitHubResponse) <-chan string {
c := make(chan string)
go func() {
for {
select {
case s := <-input1:
fmt.Println(s)
case s := <-input2:
fmt.Println(s)
}
}
}()
return c
}
func getDuckDuckGo(k string) <-chan DuckDuckGoResponse {
resp, err := http.Get("http://api.duckduckgo.com/?q=" + k + "&format=json&pretty=1")
if err != nil {
return nil
}
c := make(chan DuckDuckGoResponse)
var duckDuckParsed DuckDuckGoResponse
jsonDataFromHttp, jsonErr := ioutil.ReadAll(resp.Body)
if jsonErr != nil {
fmt.Println("Json error!")
}
defer resp.Body.Close()
if err:= json.Unmarshal(jsonDataFromHttp, &duckDuckParsed); err != nil {
panic(err)
}
return c
}
func getGitHub(k string) <-chan GitHubResponse {
resp, err := http.Get("https://api.github.com/users/?q=" + k)
if err != nil {
return nil
}
c := make(chan GitHubResponse)
var githubParsed GitHubResponse
jsonDataFromHttp, jsonErr := ioutil.ReadAll(resp.Body)
if jsonErr != nil {
fmt.Println("Json error!")
}
defer resp.Body.Close()
if err:= json.Unmarshal(jsonDataFromHttp, &githubParsed); err != nil {
panic(err)
}
return c
}
我运行这个程序,没有任何打印。
为什么?
由于
答案 0 :(得分:0)
乍一看,fanIn
函数返回一个未在主循环中读取的通道。所以是的,你正在调用返回一个频道的fanIn
函数,但没有任何东西可以读取该频道。要使渠道有用,需要消费者消费来自渠道,而另一端则需要生产者在该渠道上生产。换句话说,发送频道无法取得进展,除非另一端有人准备接收它。
接下来,您的getGitHub
和getDuckDuckGo
返回频道,但他们实际上并未在他们返回的频道上发送任何内容。此外,您真正需要的是一种调用这些功能的方法,让它们返回一个频道并仍然执行您的工作。你需要使用额外的goroutine才能让http.Get调用完成他们的工作。
最后,你的fanIn功能还会创建一个频道并将其返回,但它实际上并没有&#34;扇入&#34; input1或input2的结果。由于fanIn返回一个字符串类型的通道,因此您需要在其中写入一个字符串,该字符串可以是DuckDuckGoResponse
和GitHubResponse
之外的字段。
我恳请你们看看你想要完成的这个简化的例子:https://talks.golang.org/2012/go-docs/faninboring.go
最后一次观察您正在检查jsonErr != nil
并将其打印出来,但您可能也希望返回nil以防止代码继续运行。
我希望这能为您提供足够的洞察力,让您的代码正常运行。祝你好运!