GoLang FanIn 函数不起作用
GoLang FanIn function not working
所以我正在尝试使用 Rob Pike 的 fanin 函数编写网络爬虫。
这是我的代码 -
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
}
我运行这个程序,没有打印任何东西。
为什么?
谢谢
乍一看,fanIn
函数 return 是一个未在主循环中读取的通道。所以是的,您正在调用 fanIn
函数,其中 return 是一个频道,但没有从该频道读取任何内容。要使通道有用,需要有消费者 consuming 来自该通道,而在另一端需要有生产者 producing渠道。换句话说,除非另一端有人准备好接收,否则在频道上发送无法取得进展。
接下来是您的 getGitHub
和 getDuckDuckGo
return 频道,但它们实际上并没有在 return 的那些频道上发送任何内容。此外,您真正需要的是一种调用这些函数的方法,让它们 return 成为一个通道并仍然执行您的工作。您需要使用额外的 goroutine 才能让 http.Get 调用完成它们的工作。
最后,您的 fanIn 函数还创建了一个通道并 return 它,但实际上 "fan-in" 不是来自 input1 或 input2 的结果。由于 fanIn return 是一个字符串类型的通道,因此您需要向其中写入一个字符串,该字符串可能是 DuckDuckGoResponse
和 GitHubResponse
.
的一个字段
我建议您也看看这个您要完成的简化示例:https://talks.golang.org/2012/go-docs/faninboring.go
最后观察到您正在检查 jsonErr != nil
并将其打印出来,但您可能还想 return nil 以防止代码继续。
我希望这能给您足够的洞察力来让您的代码正常工作。祝你好运!
所以我正在尝试使用 Rob Pike 的 fanin 函数编写网络爬虫。
这是我的代码 -
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
}
我运行这个程序,没有打印任何东西。
为什么?
谢谢
乍一看,fanIn
函数 return 是一个未在主循环中读取的通道。所以是的,您正在调用 fanIn
函数,其中 return 是一个频道,但没有从该频道读取任何内容。要使通道有用,需要有消费者 consuming 来自该通道,而在另一端需要有生产者 producing渠道。换句话说,除非另一端有人准备好接收,否则在频道上发送无法取得进展。
接下来是您的 getGitHub
和 getDuckDuckGo
return 频道,但它们实际上并没有在 return 的那些频道上发送任何内容。此外,您真正需要的是一种调用这些函数的方法,让它们 return 成为一个通道并仍然执行您的工作。您需要使用额外的 goroutine 才能让 http.Get 调用完成它们的工作。
最后,您的 fanIn 函数还创建了一个通道并 return 它,但实际上 "fan-in" 不是来自 input1 或 input2 的结果。由于 fanIn return 是一个字符串类型的通道,因此您需要向其中写入一个字符串,该字符串可能是 DuckDuckGoResponse
和 GitHubResponse
.
我建议您也看看这个您要完成的简化示例:https://talks.golang.org/2012/go-docs/faninboring.go
最后观察到您正在检查 jsonErr != nil
并将其打印出来,但您可能还想 return nil 以防止代码继续。
我希望这能给您足够的洞察力来让您的代码正常工作。祝你好运!