Go结构体表示Twitter JSON结果

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

Go struct to represent twitter JSON result

问题

type TwitterResult struct{

}

var twitterUrl = "http://search.twitter.com/search.json?q=%23KOT"

func retrieveTweets(c chan<- string) {
for {
resp, err := http.Get(twitterUrl)
if err != nil {
log.Fatal(err)
}

    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    c <- string(body)
}

}

func displayTweets(c chan string) {
fmt.Println(<-c)
}

func main() {
c := make(chan string)
go retrieveTweets(c)
for {
displayTweets(c)
}

}

英文:

I've bashed up this Go twitter client below, the client still needs some work in terms of displaying the results, I'd like to represent the JSON result http://pastie.org/7298856 as a Go struct, I don't need all the fields in the JSON result, any pointers?

package main

import (
	&quot;fmt&quot;
	&quot;io/ioutil&quot;
	&quot;log&quot;
	&quot;net/http&quot;
)

type TwitterResult struct{
  
}

var twitterUrl = &quot;http://search.twitter.com/search.json?q=%23KOT&quot;

func retrieveTweets(c chan&lt;- string) {
	for {
		resp, err := http.Get(twitterUrl)
		if err != nil {
			log.Fatal(err)
		}

		defer resp.Body.Close()
		body, err := ioutil.ReadAll(resp.Body)
		c &lt;- string(body)
	}

}

func displayTweets(c chan string) {
	fmt.Println(&lt;-c)
}

func main() {
	c := make(chan string)
	go retrieveTweets(c)
	for {
		displayTweets(c)
	}

}

答案1

得分: 2

encoding/json 包提供了一种将 JSON 直接解析到结构体中的方法。以下示例解析 JSON 内容(一个映射)并将字段分配给由结构体标签标识的相应目标。例如,键 &quot;someId&quot; 被映射到具有标签 json:&quot;someId&quot; 的结构体字段。您可以在这里尝试代码 here

package main

import &quot;fmt&quot;
import &quot;encoding/json&quot;

type Example struct {
     Id    int `json:&quot;someId&quot;`
     Content string `json:&quot;someContent&quot;`
}

func main() {
	var xmpl Example

	input := `{&quot;someId&quot;: 100, &quot;someContent&quot;: &quot;foo&quot;}`
	
	json.Unmarshal([]byte(input), &amp;xmpl)
	
	fmt.Println(xmpl)
}

您可以在文档中找到有关语法的详细信息。默认情况下,结构体中未提及的字段将被忽略。

英文:

The encoding/json package offers a way to unpack JSON directly
into structs. The following example parses JSON content (a map) and assigns the fields to their
corresponding targets identified by the struct tags. E.g., the key &quot;someId&quot; is mapped to the struct
field with the tag json:&quot;someId&quot;. You can fiddle with the code here.

package main

import &quot;fmt&quot;
import &quot;encoding/json&quot;

type Example struct {
     Id    int `json:&quot;someId&quot;`
     Content string `json:&quot;someContent&quot;`
}

func main() {
	var xmpl Example

	input := `{&quot;someId&quot;: 100, &quot;someContent&quot;: &quot;foo&quot;}`
	
	json.Unmarshal([]byte(input), &amp;xmpl)
	
	fmt.Println(xmpl)
}

You can find details on the syntax in the docs.
Fields that are not mentioned in the struct are ignored by default.

答案2

得分: 0

我发现了这个https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/dNjIs-O64do,这足以指引我正确的方向。
更新:我的代码实现

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "time"
)

type twitterResult struct {
    Results []struct {
        Text     string `json:"text"`
        Ids      string `json:"id_str"`
        Name     string `json:"from_user_name"`
        Username string `json:"from_user"`
        UserId   string `json:"from_user_id_str"`
    }
}

var (
  twitterUrl = "http://search.twitter.com/search.json?q=%23UCL"
  pauseDuration = 5 * time.Second
)

func retrieveTweets(c chan<- *twitterResult) {
    for {
        resp, err := http.Get(twitterUrl)
        if err != nil {
            log.Fatal(err)
        }

        defer resp.Body.Close()
        body, err := ioutil.ReadAll(resp.Body)
        r := new(twitterResult) //or &twitterResult{} which returns *twitterResult
        err = json.Unmarshal(body, &r)
        if err != nil {
            log.Fatal(err)
        }
        c <- r
        time.Sleep(pauseDuration)
    }

}

func displayTweets(c chan *twitterResult) {
    tweets := <-c
    for _, v := range tweets.Results {
        fmt.Printf("%v:%v\n", v.Username, v.Text)
    }

}

func main() {
    c := make(chan *twitterResult)
    go retrieveTweets(c)
    for {
        displayTweets(c)
    }

}

这段代码运行得非常好,我只想知道创建一个指向结构体的通道是否符合Go的惯用方式。

英文:

I found this https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/dNjIs-O64do which is enough to point me in the right direction.
Update: my implementation of the code

package main

import (
	&quot;encoding/json&quot;
	&quot;fmt&quot;
	&quot;io/ioutil&quot;
	&quot;log&quot;
	&quot;net/http&quot;
	&quot;time&quot;
)

type twitterResult struct {
	Results []struct {
		Text     string `json:&quot;text&quot;`
		Ids      string `json:&quot;id_str&quot;`
		Name     string `json:&quot;from_user_name&quot;`
		Username string `json:&quot;from_user&quot;`
		UserId   string `json:&quot;from_user_id_str&quot;`
	}
}

var (
  twitterUrl = &quot;http://search.twitter.com/search.json?q=%23UCL&quot;
  pauseDuration = 5 * time.Second
)

func retrieveTweets(c chan&lt;- *twitterResult) {
	for {
		resp, err := http.Get(twitterUrl)
		if err != nil {
			log.Fatal(err)
		}

		defer resp.Body.Close()
		body, err := ioutil.ReadAll(resp.Body)
		r := new(twitterResult) //or &amp;twitterResult{} which returns *twitterResult
		err = json.Unmarshal(body, &amp;r)
		if err != nil {
			log.Fatal(err)
		}
		c &lt;- r
		time.Sleep(pauseDuration)
	}

}

func displayTweets(c chan *twitterResult) {
	tweets := &lt;-c
	for _, v := range tweets.Results {
		fmt.Printf(&quot;%v:%v\n&quot;, v.Username, v.Text)
	}

}

func main() {
	c := make(chan *twitterResult)
	go retrieveTweets(c)
	for {
		displayTweets(c)
	}

}

The code works very well, I only wonder if creating a channel that is a pointer to a struct is idiomatic Go.

huangapple
  • 本文由 发表于 2013年4月3日 18:25:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/15784835.html
匿名

发表评论

匿名网友

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

确定