mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2025-09-14 23:51:34 +00:00
deploy: 06a1bdf735
This commit is contained in:
79
vendor/gopl.io/ch4/append/main.go
generated
vendored
Normal file
79
vendor/gopl.io/ch4/append/main.go
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
|
||||
// See page 88.
|
||||
|
||||
// Append illustrates the behavior of the built-in append function.
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func appendslice(x []int, y ...int) []int {
|
||||
var z []int
|
||||
zlen := len(x) + len(y)
|
||||
if zlen <= cap(x) {
|
||||
// There is room to expand the slice.
|
||||
z = x[:zlen]
|
||||
} else {
|
||||
// There is insufficient space.
|
||||
// Grow by doubling, for amortized linear complexity.
|
||||
zcap := zlen
|
||||
if zcap < 2*len(x) {
|
||||
zcap = 2 * len(x)
|
||||
}
|
||||
z = make([]int, zlen, zcap)
|
||||
copy(z, x)
|
||||
}
|
||||
copy(z[len(x):], y)
|
||||
return z
|
||||
}
|
||||
|
||||
//!+append
|
||||
func appendInt(x []int, y int) []int {
|
||||
var z []int
|
||||
zlen := len(x) + 1
|
||||
if zlen <= cap(x) {
|
||||
// There is room to grow. Extend the slice.
|
||||
z = x[:zlen]
|
||||
} else {
|
||||
// There is insufficient space. Allocate a new array.
|
||||
// Grow by doubling, for amortized linear complexity.
|
||||
zcap := zlen
|
||||
if zcap < 2*len(x) {
|
||||
zcap = 2 * len(x)
|
||||
}
|
||||
z = make([]int, zlen, zcap)
|
||||
copy(z, x) // a built-in function; see text
|
||||
}
|
||||
z[len(x)] = y
|
||||
return z
|
||||
}
|
||||
|
||||
//!-append
|
||||
|
||||
//!+growth
|
||||
func main() {
|
||||
var x, y []int
|
||||
for i := 0; i < 10; i++ {
|
||||
y = appendInt(x, i)
|
||||
fmt.Printf("%d cap=%d\t%v\n", i, cap(y), y)
|
||||
x = y
|
||||
}
|
||||
}
|
||||
|
||||
//!-growth
|
||||
|
||||
/*
|
||||
//!+output
|
||||
0 cap=1 [0]
|
||||
1 cap=2 [0 1]
|
||||
2 cap=4 [0 1 2]
|
||||
3 cap=4 [0 1 2 3]
|
||||
4 cap=8 [0 1 2 3 4]
|
||||
5 cap=8 [0 1 2 3 4 5]
|
||||
6 cap=8 [0 1 2 3 4 5 6]
|
||||
7 cap=8 [0 1 2 3 4 5 6 7]
|
||||
8 cap=16 [0 1 2 3 4 5 6 7 8]
|
||||
9 cap=16 [0 1 2 3 4 5 6 7 8 9]
|
||||
//!-output
|
||||
*/
|
30
vendor/gopl.io/ch4/autoescape/main.go
generated
vendored
Normal file
30
vendor/gopl.io/ch4/autoescape/main.go
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
|
||||
// See page 117.
|
||||
|
||||
// Autoescape demonstrates automatic HTML escaping in html/template.
|
||||
package main
|
||||
|
||||
import (
|
||||
"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 text
|
||||
B template.HTML // trusted HTML
|
||||
}
|
||||
data.A = "<b>Hello!</b>"
|
||||
data.B = "<b>Hello!</b>"
|
||||
if err := t.Execute(os.Stdout, data); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
//!-
|
56
vendor/gopl.io/ch4/charcount/main.go
generated
vendored
Normal file
56
vendor/gopl.io/ch4/charcount/main.go
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
|
||||
// See page 97.
|
||||
//!+
|
||||
|
||||
// Charcount computes counts of Unicode characters.
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
func main() {
|
||||
counts := make(map[rune]int) // counts of Unicode characters
|
||||
var utflen [utf8.UTFMax + 1]int // count of lengths of UTF-8 encodings
|
||||
invalid := 0 // count of invalid UTF-8 characters
|
||||
|
||||
in := bufio.NewReader(os.Stdin)
|
||||
for {
|
||||
r, n, err := in.ReadRune() // returns rune, nbytes, error
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "charcount: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if r == unicode.ReplacementChar && n == 1 {
|
||||
invalid++
|
||||
continue
|
||||
}
|
||||
counts[r]++
|
||||
utflen[n]++
|
||||
}
|
||||
fmt.Printf("rune\tcount\n")
|
||||
for c, n := range counts {
|
||||
fmt.Printf("%q\t%d\n", c, n)
|
||||
}
|
||||
fmt.Print("\nlen\tcount\n")
|
||||
for i, n := range utflen {
|
||||
if i > 0 {
|
||||
fmt.Printf("%d\t%d\n", i, n)
|
||||
}
|
||||
}
|
||||
if invalid > 0 {
|
||||
fmt.Printf("\n%d invalid UTF-8 characters\n", invalid)
|
||||
}
|
||||
}
|
||||
|
||||
//!-
|
33
vendor/gopl.io/ch4/dedup/main.go
generated
vendored
Normal file
33
vendor/gopl.io/ch4/dedup/main.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
|
||||
// See page 96.
|
||||
|
||||
// Dedup prints only one instance of each line; duplicates are removed.
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
//!+
|
||||
func main() {
|
||||
seen := make(map[string]bool) // a set of strings
|
||||
input := bufio.NewScanner(os.Stdin)
|
||||
for input.Scan() {
|
||||
line := input.Text()
|
||||
if !seen[line] {
|
||||
seen[line] = true
|
||||
fmt.Println(line)
|
||||
}
|
||||
}
|
||||
|
||||
if err := input.Err(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "dedup: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
//!-
|
46
vendor/gopl.io/ch4/embed/main.go
generated
vendored
Normal file
46
vendor/gopl.io/ch4/embed/main.go
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
|
||||
// See page 106.
|
||||
|
||||
// Embed demonstrates basic struct embedding.
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Point struct{ X, Y int }
|
||||
|
||||
type Circle struct {
|
||||
Point
|
||||
Radius int
|
||||
}
|
||||
|
||||
type Wheel struct {
|
||||
Circle
|
||||
Spokes int
|
||||
}
|
||||
|
||||
func main() {
|
||||
var w Wheel
|
||||
//!+
|
||||
w = Wheel{Circle{Point{8, 8}, 5}, 20}
|
||||
|
||||
w = Wheel{
|
||||
Circle: Circle{
|
||||
Point: Point{X: 8, Y: 8},
|
||||
Radius: 5,
|
||||
},
|
||||
Spokes: 20, // NOTE: trailing comma necessary here (and at Radius)
|
||||
}
|
||||
|
||||
fmt.Printf("%#v\n", w)
|
||||
// Output:
|
||||
// Wheel{Circle:Circle{Point:Point{X:8, Y:8}, Radius:5}, Spokes:20}
|
||||
|
||||
w.X = 42
|
||||
|
||||
fmt.Printf("%#v\n", w)
|
||||
// Output:
|
||||
// Wheel{Circle:Circle{Point:Point{X:42, Y:8}, Radius:5}, Spokes:20}
|
||||
//!-
|
||||
}
|
35
vendor/gopl.io/ch4/github/github.go
generated
vendored
Normal file
35
vendor/gopl.io/ch4/github/github.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
|
||||
// See page 110.
|
||||
//!+
|
||||
|
||||
// Package github provides a Go API for the GitHub issue tracker.
|
||||
// See https://developer.github.com/v3/search/#search-issues.
|
||||
package github
|
||||
|
||||
import "time"
|
||||
|
||||
const IssuesURL = "https://api.github.com/search/issues"
|
||||
|
||||
type IssuesSearchResult struct {
|
||||
TotalCount int `json:"total_count"`
|
||||
Items []*Issue
|
||||
}
|
||||
|
||||
type Issue struct {
|
||||
Number int
|
||||
HTMLURL string `json:"html_url"`
|
||||
Title string
|
||||
State string
|
||||
User *User
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Body string // in Markdown format
|
||||
}
|
||||
|
||||
type User struct {
|
||||
Login string
|
||||
HTMLURL string `json:"html_url"`
|
||||
}
|
||||
|
||||
//!-
|
53
vendor/gopl.io/ch4/github/search.go
generated
vendored
Normal file
53
vendor/gopl.io/ch4/github/search.go
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
|
||||
//!+
|
||||
|
||||
package github
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 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
|
||||
}
|
||||
//!-
|
||||
// For long-term stability, instead of http.Get, use the
|
||||
// variant below which adds an HTTP request header indicating
|
||||
// that only version 3 of the GitHub API is acceptable.
|
||||
//
|
||||
// req, err := http.NewRequest("GET", IssuesURL+"?q="+q, nil)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// req.Header.Set(
|
||||
// "Accept", "application/vnd.github.v3.text-match+json")
|
||||
// resp, err := http.DefaultClient.Do(req)
|
||||
//!+
|
||||
|
||||
// We must close resp.Body on all execution paths.
|
||||
// (Chapter 5 presents 'defer', which makes this simpler.)
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
resp.Body.Close()
|
||||
return nil, fmt.Errorf("search query failed: %s", resp.Status)
|
||||
}
|
||||
|
||||
var result IssuesSearchResult
|
||||
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
||||
resp.Body.Close()
|
||||
return nil, err
|
||||
}
|
||||
resp.Body.Close()
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
//!-
|
43
vendor/gopl.io/ch4/graph/main.go
generated
vendored
Normal file
43
vendor/gopl.io/ch4/graph/main.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
|
||||
// See page 99.
|
||||
|
||||
// Graph shows how to use a map of maps to represent a directed graph.
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
//!+
|
||||
var graph = make(map[string]map[string]bool)
|
||||
|
||||
func addEdge(from, to string) {
|
||||
edges := graph[from]
|
||||
if edges == nil {
|
||||
edges = make(map[string]bool)
|
||||
graph[from] = edges
|
||||
}
|
||||
edges[to] = true
|
||||
}
|
||||
|
||||
func hasEdge(from, to string) bool {
|
||||
return graph[from][to]
|
||||
}
|
||||
|
||||
//!-
|
||||
|
||||
func main() {
|
||||
addEdge("a", "b")
|
||||
addEdge("c", "d")
|
||||
addEdge("a", "d")
|
||||
addEdge("d", "a")
|
||||
fmt.Println(hasEdge("a", "b"))
|
||||
fmt.Println(hasEdge("c", "d"))
|
||||
fmt.Println(hasEdge("a", "d"))
|
||||
fmt.Println(hasEdge("d", "a"))
|
||||
fmt.Println(hasEdge("x", "b"))
|
||||
fmt.Println(hasEdge("c", "d"))
|
||||
fmt.Println(hasEdge("x", "d"))
|
||||
fmt.Println(hasEdge("d", "x"))
|
||||
|
||||
}
|
52
vendor/gopl.io/ch4/issues/main.go
generated
vendored
Normal file
52
vendor/gopl.io/ch4/issues/main.go
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
|
||||
// See page 112.
|
||||
//!+
|
||||
|
||||
// Issues prints a table of GitHub issues matching the search terms.
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"gopl.io/ch4/github"
|
||||
)
|
||||
|
||||
//!+
|
||||
func main() {
|
||||
result, err := github.SearchIssues(os.Args[1:])
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("%d issues:\n", result.TotalCount)
|
||||
for _, item := range result.Items {
|
||||
fmt.Printf("#%-5d %9.9s %.55s\n",
|
||||
item.Number, item.User.Login, item.Title)
|
||||
}
|
||||
}
|
||||
|
||||
//!-
|
||||
|
||||
/*
|
||||
//!+textoutput
|
||||
$ go build gopl.io/ch4/issues
|
||||
$ ./issues repo:golang/go is:open json decoder
|
||||
13 issues:
|
||||
#5680 eaigner encoding/json: set key converter on en/decoder
|
||||
#6050 gopherbot encoding/json: provide tokenizer
|
||||
#8658 gopherbot encoding/json: use bufio
|
||||
#8462 kortschak encoding/json: UnmarshalText confuses json.Unmarshal
|
||||
#5901 rsc encoding/json: allow override type marshaling
|
||||
#9812 klauspost encoding/json: string tag not symmetric
|
||||
#7872 extempora encoding/json: Encoder internally buffers full output
|
||||
#9650 cespare encoding/json: Decoding gives errPhase when unmarshalin
|
||||
#6716 gopherbot encoding/json: include field name in unmarshal error me
|
||||
#6901 lukescott encoding/json, encoding/xml: option to treat unknown fi
|
||||
#6384 joeshaw encoding/json: encode precise floating point integers u
|
||||
#6647 btracey x/tools/cmd/godoc: display type kind of each named type
|
||||
#4237 gjemiller encoding/base64: URLEncoding padding is optional
|
||||
//!-textoutput
|
||||
*/
|
52
vendor/gopl.io/ch4/issueshtml/main.go
generated
vendored
Normal file
52
vendor/gopl.io/ch4/issueshtml/main.go
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
|
||||
// See page 115.
|
||||
|
||||
// Issueshtml prints an HTML table of issues matching the search terms.
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"gopl.io/ch4/github"
|
||||
)
|
||||
|
||||
//!+template
|
||||
import "html/template"
|
||||
|
||||
var issueList = template.Must(template.New("issuelist").Parse(`
|
||||
<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>
|
||||
`))
|
||||
|
||||
//!-template
|
||||
|
||||
//!+
|
||||
func main() {
|
||||
result, err := github.SearchIssues(os.Args[1:])
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if err := issueList.Execute(os.Stdout, result); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
//!-
|
89
vendor/gopl.io/ch4/issuesreport/main.go
generated
vendored
Normal file
89
vendor/gopl.io/ch4/issuesreport/main.go
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
|
||||
// See page 113.
|
||||
|
||||
// Issuesreport prints a report of issues matching the search terms.
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"gopl.io/ch4/github"
|
||||
)
|
||||
|
||||
//!+template
|
||||
const templ = `{{.TotalCount}} issues:
|
||||
{{range .Items}}----------------------------------------
|
||||
Number: {{.Number}}
|
||||
User: {{.User.Login}}
|
||||
Title: {{.Title | printf "%.64s"}}
|
||||
Age: {{.CreatedAt | daysAgo}} days
|
||||
{{end}}`
|
||||
|
||||
//!-template
|
||||
|
||||
//!+daysAgo
|
||||
func daysAgo(t time.Time) int {
|
||||
return int(time.Since(t).Hours() / 24)
|
||||
}
|
||||
|
||||
//!-daysAgo
|
||||
|
||||
//!+exec
|
||||
var report = template.Must(template.New("issuelist").
|
||||
Funcs(template.FuncMap{"daysAgo": daysAgo}).
|
||||
Parse(templ))
|
||||
|
||||
func main() {
|
||||
result, err := github.SearchIssues(os.Args[1:])
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if err := report.Execute(os.Stdout, result); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
//!-exec
|
||||
|
||||
func noMust() {
|
||||
//!+parse
|
||||
report, err := template.New("report").
|
||||
Funcs(template.FuncMap{"daysAgo": daysAgo}).
|
||||
Parse(templ)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
//!-parse
|
||||
result, err := github.SearchIssues(os.Args[1:])
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if err := report.Execute(os.Stdout, result); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
//!+output
|
||||
$ go build gopl.io/ch4/issuesreport
|
||||
$ ./issuesreport repo:golang/go is:open json decoder
|
||||
13 issues:
|
||||
----------------------------------------
|
||||
Number: 5680
|
||||
User: eaigner
|
||||
Title: encoding/json: set key converter on en/decoder
|
||||
Age: 750 days
|
||||
----------------------------------------
|
||||
Number: 6050
|
||||
User: gopherbot
|
||||
Title: encoding/json: provide tokenizer
|
||||
Age: 695 days
|
||||
----------------------------------------
|
||||
...
|
||||
//!-output
|
||||
*/
|
104
vendor/gopl.io/ch4/movie/main.go
generated
vendored
Normal file
104
vendor/gopl.io/ch4/movie/main.go
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
|
||||
// See page 108.
|
||||
|
||||
// Movie prints Movies as JSON.
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
//!+
|
||||
type Movie struct {
|
||||
Title string
|
||||
Year int `json:"released"`
|
||||
Color bool `json:"color,omitempty"`
|
||||
Actors []string
|
||||
}
|
||||
|
||||
var movies = []Movie{
|
||||
{Title: "Casablanca", Year: 1942, Color: false,
|
||||
Actors: []string{"Humphrey Bogart", "Ingrid Bergman"}},
|
||||
{Title: "Cool Hand Luke", Year: 1967, Color: true,
|
||||
Actors: []string{"Paul Newman"}},
|
||||
{Title: "Bullitt", Year: 1968, Color: true,
|
||||
Actors: []string{"Steve McQueen", "Jacqueline Bisset"}},
|
||||
// ...
|
||||
}
|
||||
|
||||
//!-
|
||||
|
||||
func main() {
|
||||
{
|
||||
//!+Marshal
|
||||
data, err := json.Marshal(movies)
|
||||
if err != nil {
|
||||
log.Fatalf("JSON marshaling failed: %s", err)
|
||||
}
|
||||
fmt.Printf("%s\n", data)
|
||||
//!-Marshal
|
||||
}
|
||||
|
||||
{
|
||||
//!+MarshalIndent
|
||||
data, err := json.MarshalIndent(movies, "", " ")
|
||||
if err != nil {
|
||||
log.Fatalf("JSON marshaling failed: %s", err)
|
||||
}
|
||||
fmt.Printf("%s\n", data)
|
||||
//!-MarshalIndent
|
||||
|
||||
//!+Unmarshal
|
||||
var titles []struct{ Title string }
|
||||
if err := json.Unmarshal(data, &titles); err != nil {
|
||||
log.Fatalf("JSON unmarshaling failed: %s", err)
|
||||
}
|
||||
fmt.Println(titles) // "[{Casablanca} {Cool Hand Luke} {Bullitt}]"
|
||||
//!-Unmarshal
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
//!+output
|
||||
[{"Title":"Casablanca","released":1942,"Actors":["Humphrey Bogart","Ingr
|
||||
id Bergman"]},{"Title":"Cool Hand Luke","released":1967,"color":true,"Ac
|
||||
tors":["Paul Newman"]},{"Title":"Bullitt","released":1968,"color":true,"
|
||||
Actors":["Steve McQueen","Jacqueline Bisset"]}]
|
||||
//!-output
|
||||
*/
|
||||
|
||||
/*
|
||||
//!+indented
|
||||
[
|
||||
{
|
||||
"Title": "Casablanca",
|
||||
"released": 1942,
|
||||
"Actors": [
|
||||
"Humphrey Bogart",
|
||||
"Ingrid Bergman"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Title": "Cool Hand Luke",
|
||||
"released": 1967,
|
||||
"color": true,
|
||||
"Actors": [
|
||||
"Paul Newman"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Title": "Bullitt",
|
||||
"released": 1968,
|
||||
"color": true,
|
||||
"Actors": [
|
||||
"Steve McQueen",
|
||||
"Jacqueline Bisset"
|
||||
]
|
||||
}
|
||||
]
|
||||
//!-indented
|
||||
*/
|
47
vendor/gopl.io/ch4/nonempty/main.go
generated
vendored
Normal file
47
vendor/gopl.io/ch4/nonempty/main.go
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
|
||||
// See page 91.
|
||||
|
||||
//!+nonempty
|
||||
|
||||
// Nonempty is an example of an in-place slice algorithm.
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
// nonempty returns a slice holding only the non-empty strings.
|
||||
// The underlying array is modified during the call.
|
||||
func nonempty(strings []string) []string {
|
||||
i := 0
|
||||
for _, s := range strings {
|
||||
if s != "" {
|
||||
strings[i] = s
|
||||
i++
|
||||
}
|
||||
}
|
||||
return strings[:i]
|
||||
}
|
||||
|
||||
//!-nonempty
|
||||
|
||||
func main() {
|
||||
//!+main
|
||||
data := []string{"one", "", "three"}
|
||||
fmt.Printf("%q\n", nonempty(data)) // `["one" "three"]`
|
||||
fmt.Printf("%q\n", data) // `["one" "three" "three"]`
|
||||
//!-main
|
||||
}
|
||||
|
||||
//!+alt
|
||||
func nonempty2(strings []string) []string {
|
||||
out := strings[:0] // zero-length slice of original
|
||||
for _, s := range strings {
|
||||
if s != "" {
|
||||
out = append(out, s)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
//!-alt
|
60
vendor/gopl.io/ch4/rev/main.go
generated
vendored
Normal file
60
vendor/gopl.io/ch4/rev/main.go
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
|
||||
// See page 86.
|
||||
|
||||
// Rev reverses a slice.
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
//!+array
|
||||
a := [...]int{0, 1, 2, 3, 4, 5}
|
||||
reverse(a[:])
|
||||
fmt.Println(a) // "[5 4 3 2 1 0]"
|
||||
//!-array
|
||||
|
||||
//!+slice
|
||||
s := []int{0, 1, 2, 3, 4, 5}
|
||||
// Rotate s left by two positions.
|
||||
reverse(s[:2])
|
||||
reverse(s[2:])
|
||||
reverse(s)
|
||||
fmt.Println(s) // "[2 3 4 5 0 1]"
|
||||
//!-slice
|
||||
|
||||
// Interactive test of reverse.
|
||||
input := bufio.NewScanner(os.Stdin)
|
||||
outer:
|
||||
for input.Scan() {
|
||||
var ints []int
|
||||
for _, s := range strings.Fields(input.Text()) {
|
||||
x, err := strconv.ParseInt(s, 10, 64)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
continue outer
|
||||
}
|
||||
ints = append(ints, int(x))
|
||||
}
|
||||
reverse(ints)
|
||||
fmt.Printf("%v\n", ints)
|
||||
}
|
||||
// NOTE: ignoring potential errors from input.Err()
|
||||
}
|
||||
|
||||
//!+rev
|
||||
// reverse reverses a slice of ints in place.
|
||||
func reverse(s []int) {
|
||||
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
}
|
||||
|
||||
//!-rev
|
25
vendor/gopl.io/ch4/sha256/main.go
generated
vendored
Normal file
25
vendor/gopl.io/ch4/sha256/main.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
|
||||
// See page 83.
|
||||
|
||||
// The sha256 command computes the SHA256 hash (an array) of a string.
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
//!+
|
||||
import "crypto/sha256"
|
||||
|
||||
func main() {
|
||||
c1 := sha256.Sum256([]byte("x"))
|
||||
c2 := sha256.Sum256([]byte("X"))
|
||||
fmt.Printf("%x\n%x\n%t\n%T\n", c1, c2, c1 == c2, c1)
|
||||
// Output:
|
||||
// 2d711642b726b04401627ca9fbac32f5c8530fb1903cc4db02258717921a4881
|
||||
// 4b68ab3847feda7d6c62c1fbcbeebfa35eab7351ed5e78f4ddadea5df64b8015
|
||||
// false
|
||||
// [32]uint8
|
||||
}
|
||||
|
||||
//!-
|
50
vendor/gopl.io/ch4/treesort/sort.go
generated
vendored
Normal file
50
vendor/gopl.io/ch4/treesort/sort.go
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
|
||||
// See page 101.
|
||||
|
||||
// Package treesort provides insertion sort using an unbalanced binary tree.
|
||||
package treesort
|
||||
|
||||
//!+
|
||||
type tree struct {
|
||||
value int
|
||||
left, right *tree
|
||||
}
|
||||
|
||||
// Sort sorts values in place.
|
||||
func Sort(values []int) {
|
||||
var root *tree
|
||||
for _, v := range values {
|
||||
root = add(root, v)
|
||||
}
|
||||
appendValues(values[:0], root)
|
||||
}
|
||||
|
||||
// appendValues appends the elements of t to values in order
|
||||
// and returns the resulting slice.
|
||||
func appendValues(values []int, t *tree) []int {
|
||||
if t != nil {
|
||||
values = appendValues(values, t.left)
|
||||
values = append(values, t.value)
|
||||
values = appendValues(values, t.right)
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
func add(t *tree, value int) *tree {
|
||||
if t == nil {
|
||||
// Equivalent to return &tree{value: value}.
|
||||
t = new(tree)
|
||||
t.value = value
|
||||
return t
|
||||
}
|
||||
if value < t.value {
|
||||
t.left = add(t.left, value)
|
||||
} else {
|
||||
t.right = add(t.right, value)
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
//!-
|
23
vendor/gopl.io/ch4/treesort/sort_test.go
generated
vendored
Normal file
23
vendor/gopl.io/ch4/treesort/sort_test.go
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
|
||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
|
||||
package treesort_test
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"gopl.io/ch4/treesort"
|
||||
)
|
||||
|
||||
func TestSort(t *testing.T) {
|
||||
data := make([]int, 50)
|
||||
for i := range data {
|
||||
data[i] = rand.Int() % 50
|
||||
}
|
||||
treesort.Sort(data)
|
||||
if !sort.IntsAreSorted(data) {
|
||||
t.Errorf("not sorted: %v", data)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user