简单json使用
package mainimport ("encoding/json""fmt""log")type Movie struct {Name string `json:"name"`Year int32 `json:"year"`Actors []string}func main() {movies := []Movie{{Name: "a",Year: 2016,Actors: []string{"wht1", "wht2",},},}data, err := json.MarshalIndent(movies, "", "\t")if err != nil {log.Fatal(err)}fmt.Println(string(data))}
text/template
package mainimport ("encoding/json""fmt""log""net/http""net/url""os""strings""text/template""time")const IssuesURL = "https://api.github.com/search/issues"type IssuesSearchResult struct {TotalCount int `json:"total_count"`Items []*Issue}type Issue struct {Number intHTMLURL string `json:"html_url"`Title stringState stringUser *UserCreatedAt time.Time `json:"created_at"`Body string // in Markdown format}type User struct {Login stringHTMLURL string `json:"html_url"`}// SearchIssues queries the GitHub issue tracker.func SearchIssues(terms []string) (*IssuesSearchResult, error) {q := url.QueryEscape(strings.Join(terms, " "))resp, err := http.Get(IssuesURL + "?q=" + q)if err != nil {return nil, err}// We must close resp.Body on all execution paths.// (Chapter 5 presents 'defer', which makes this simpler.)if resp.StatusCode != http.StatusOK {err := resp.Body.Close()if err != nil {return nil, err}return nil, fmt.Errorf("search query failed: %s", resp.Status)}var result IssuesSearchResultif err := json.NewDecoder(resp.Body).Decode(&result); err != nil {err := resp.Body.Close()if err != nil {return nil, err}return nil, err}err = resp.Body.Close()if err != nil {return nil, err}return &result, nil}func daysAgo(t time.Time) int32 {return int32(time.Since(t).Hours() / 24)}const templ = `{{.TotalCount}} issues:{{range .Items}}----------------------------------------Number: {{.Number}}User: {{.User.Login}}Title: {{.Title | printf "%.64s"}}Age: {{.CreatedAt | daysAgo}} days{{end}}`var report = template.Must(template.New("issueList").Funcs(template.FuncMap{"daysAgo": daysAgo}).Parse(templ))func main() {result, err := SearchIssues([]string{"Hello"})if err != nil {log.Fatal(err)}if err = report.Execute(os.Stdout, result); err != nil {log.Fatal(err)}}
html/template
相比于text/template,html/template会自动转义特殊字符。
package mainimport ("encoding/json""fmt""html/template""log""net/http""net/url""os""strings""time")const IssuesURL = "https://api.github.com/search/issues"type IssuesSearchResult struct {TotalCount int `json:"total_count"`Items []*Issue}type Issue struct {Number intHTMLURL string `json:"html_url"`Title stringState stringUser *UserCreatedAt time.Time `json:"created_at"`Body string // in Markdown format}type User struct {Login stringHTMLURL string `json:"html_url"`}// SearchIssues queries the GitHub issue tracker.func SearchIssues(terms []string) (*IssuesSearchResult, error) {q := url.QueryEscape(strings.Join(terms, " "))resp, err := http.Get(IssuesURL + "?q=" + q)if err != nil {return nil, err}// We must close resp.Body on all execution paths.// (Chapter 5 presents 'defer', which makes this simpler.)if resp.StatusCode != http.StatusOK {err := resp.Body.Close()if err != nil {return nil, err}return nil, fmt.Errorf("search query failed: %s", resp.Status)}var result IssuesSearchResultif err := json.NewDecoder(resp.Body).Decode(&result); err != nil {err := resp.Body.Close()if err != nil {return nil, err}return nil, err}err = resp.Body.Close()if err != nil {return nil, err}return &result, nil}func daysAgo(t time.Time) int32 {return int32(time.Since(t).Hours() / 24)}const templ = `<h1>{{.TotalCount}} issues</h1><table><tr style='text-align: left'><th>#</th><th>State</th><th>User</th><th>Title</th></tr>{{range .Items}}<tr><td><a href='{{.HTMLURL}}'>{{.Number}}</a></td><td>{{.State}}</td><td><a href='{{.User.HTMLURL}}'>{{.User.Login}}</a></td><td><a href='{{.HTMLURL}}'>{{.Title}}</a></td></tr>{{end}}</table>`var report = template.Must(template.New("issueList").Funcs(template.FuncMap{"daysAgo": daysAgo}).Parse(templ))func main() {result, err := SearchIssues([]string{"repo:golang/go", "3133", "10535"})if err != nil {log.Fatal(err)}f, err := os.OpenFile("index.html", os.O_RDWR|os.O_CREATE, 0666)if err != nil {log.Fatal(err)}if err = report.Execute(f, result); err != nil {log.Fatal(err)}}
package mainimport ("html/template""log""os")func main() {const templ = `<p>A: {{.A}}</p><p>B: {{.B}}</p>`t := template.Must(template.New("escape").Parse(templ))var data struct {A string // untrusted plain textB template.HTML // trusted HTML}data.A = "<b>Hello!</b>"data.B = "<b>Hello!</b>"f, err := os.OpenFile("index.html", os.O_TRUNC | os.O_CREATE, 0666)if err != nil {log.Fatal(err)}if err := t.Execute(f, data); err != nil {log.Fatal(err)}}

可以看到template.HTML中的字符串不会被转义
