mirror of
https://github.com/golang/go
synced 2024-11-13 17:00:22 -07:00
godoc: make example code more readable with new comment convention
go/doc: move Examples to go/ast cmd/go: use go/doc to read examples src/pkg: update examples to use new convention This is to make whole file examples more readable. When presented as a complete function, preceding an Example with its output is confusing. The new convention is to put the expected output in the final comment of the example, preceded by the string "output:" (case insensitive). An idiomatic example looks like this: // This example demonstrates Foo by doing bar and quux. func ExampleFoo() { // example body that does bar and quux // Output: // example output } R=rsc, gri CC=golang-dev https://golang.org/cl/5673053
This commit is contained in:
parent
fa0100cf26
commit
11e113db57
@ -183,9 +183,9 @@ where xxx is a suffix not beginning with an upper case letter.
|
|||||||
|
|
||||||
Here is an example of an example:
|
Here is an example of an example:
|
||||||
|
|
||||||
// The output of this example function.
|
|
||||||
func ExamplePrintln() {
|
func ExamplePrintln() {
|
||||||
Println("The output of this example function.")
|
Println("The output of this example function.")
|
||||||
|
// Output: The output of this example function.
|
||||||
}
|
}
|
||||||
|
|
||||||
The entire test file is presented as the example when it contains a single
|
The entire test file is presented as the example when it contains a single
|
||||||
@ -717,17 +717,16 @@ func (t *testFuncs) load(filename, pkg string, seen *bool) error {
|
|||||||
case isTest(name, "Benchmark"):
|
case isTest(name, "Benchmark"):
|
||||||
t.Benchmarks = append(t.Benchmarks, testFunc{pkg, name, ""})
|
t.Benchmarks = append(t.Benchmarks, testFunc{pkg, name, ""})
|
||||||
*seen = true
|
*seen = true
|
||||||
case isTest(name, "Example"):
|
|
||||||
output := n.Doc.Text()
|
|
||||||
if output == "" {
|
|
||||||
// Don't run examples with no output.
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
t.Examples = append(t.Examples, testFunc{pkg, name, output})
|
|
||||||
*seen = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for _, e := range ast.Examples(f) {
|
||||||
|
if e.Output == "" {
|
||||||
|
// Don't run examples with no output.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
t.Examples = append(t.Examples, testFunc{pkg, "Example" + e.Name, e.Output})
|
||||||
|
*seen = true
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,7 +499,9 @@ func startsWithUppercase(s string) bool {
|
|||||||
return unicode.IsUpper(r)
|
return unicode.IsUpper(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func example_htmlFunc(funcName string, examples []*doc.Example, fset *token.FileSet) string {
|
var exampleOutputRx = regexp.MustCompile(`(?i)//[[:space:]]*output:`)
|
||||||
|
|
||||||
|
func example_htmlFunc(funcName string, examples []*ast.Example, fset *token.FileSet) string {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
for _, eg := range examples {
|
for _, eg := range examples {
|
||||||
name := eg.Name
|
name := eg.Name
|
||||||
@ -517,16 +519,28 @@ func example_htmlFunc(funcName string, examples []*doc.Example, fset *token.File
|
|||||||
}
|
}
|
||||||
|
|
||||||
// print code
|
// print code
|
||||||
code := node_htmlFunc(eg.Body, fset)
|
cnode := &printer.CommentedNode{Node: eg.Code, Comments: eg.Comments}
|
||||||
|
code := node_htmlFunc(cnode, fset)
|
||||||
|
out := eg.Output
|
||||||
|
|
||||||
|
// additional formatting if this is a function body
|
||||||
if len(code) > 0 && code[0] == '{' {
|
if len(code) > 0 && code[0] == '{' {
|
||||||
// unindent and remove surrounding braces
|
// unindent
|
||||||
code = strings.Replace(code, "\n ", "\n", -1)
|
code = strings.Replace(code, "\n ", "\n", -1)
|
||||||
|
// remove surrounding braces
|
||||||
code = code[2 : len(code)-2]
|
code = code[2 : len(code)-2]
|
||||||
|
// remove output comment
|
||||||
|
if loc := exampleOutputRx.FindStringIndex(code); loc != nil {
|
||||||
|
code = strings.TrimSpace(code[:loc[0]])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// drop output, as the output comment will appear in the code
|
||||||
|
out = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
err := exampleHTML.Execute(&buf, struct {
|
err := exampleHTML.Execute(&buf, struct {
|
||||||
Name, Code, Output string
|
Name, Code, Output string
|
||||||
}{eg.Name, code, eg.Output})
|
}{eg.Name, code, out})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
}
|
}
|
||||||
@ -552,7 +566,6 @@ func example_nameFunc(s string) string {
|
|||||||
func example_suffixFunc(name string) string {
|
func example_suffixFunc(name string) string {
|
||||||
_, suffix := splitExampleName(name)
|
_, suffix := splitExampleName(name)
|
||||||
return suffix
|
return suffix
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func splitExampleName(s string) (name, suffix string) {
|
func splitExampleName(s string) (name, suffix string) {
|
||||||
@ -966,7 +979,7 @@ type PageInfo struct {
|
|||||||
FSet *token.FileSet // corresponding file set
|
FSet *token.FileSet // corresponding file set
|
||||||
PAst *ast.File // nil if no single AST with package exports
|
PAst *ast.File // nil if no single AST with package exports
|
||||||
PDoc *doc.Package // nil if no single package documentation
|
PDoc *doc.Package // nil if no single package documentation
|
||||||
Examples []*doc.Example // nil if no example code
|
Examples []*ast.Example // nil if no example code
|
||||||
Dirs *DirList // nil if no directory information
|
Dirs *DirList // nil if no directory information
|
||||||
DirTime time.Time // directory time stamp
|
DirTime time.Time // directory time stamp
|
||||||
DirFlat bool // if set, show directory in a flat (non-indented) manner
|
DirFlat bool // if set, show directory in a flat (non-indented) manner
|
||||||
@ -1115,7 +1128,7 @@ func (h *httpHandler) getPageInfo(abspath, relpath, pkgname string, mode PageInf
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get examples from *_test.go files
|
// get examples from *_test.go files
|
||||||
var examples []*doc.Example
|
var examples []*ast.Example
|
||||||
filter = func(d os.FileInfo) bool {
|
filter = func(d os.FileInfo) bool {
|
||||||
return isGoFile(d) && strings.HasSuffix(d.Name(), "_test.go")
|
return isGoFile(d) && strings.HasSuffix(d.Name(), "_test.go")
|
||||||
}
|
}
|
||||||
@ -1123,7 +1136,11 @@ func (h *httpHandler) getPageInfo(abspath, relpath, pkgname string, mode PageInf
|
|||||||
log.Println("parsing test files:", err)
|
log.Println("parsing test files:", err)
|
||||||
} else {
|
} else {
|
||||||
for _, testpkg := range testpkgs {
|
for _, testpkg := range testpkgs {
|
||||||
examples = append(examples, doc.Examples(testpkg)...)
|
var files []*ast.File
|
||||||
|
for _, f := range testpkg.Files {
|
||||||
|
files = append(files, f)
|
||||||
|
}
|
||||||
|
examples = append(examples, ast.Examples(files...)...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,18 +11,18 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Hello world!
|
|
||||||
func ExampleBuffer() {
|
func ExampleBuffer() {
|
||||||
var b Buffer // A Buffer needs no initialization.
|
var b Buffer // A Buffer needs no initialization.
|
||||||
b.Write([]byte("Hello "))
|
b.Write([]byte("Hello "))
|
||||||
b.Write([]byte("world!"))
|
b.Write([]byte("world!"))
|
||||||
b.WriteTo(os.Stdout)
|
b.WriteTo(os.Stdout)
|
||||||
|
// Output: Hello world!
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gophers rule!
|
|
||||||
func ExampleBuffer_reader() {
|
func ExampleBuffer_reader() {
|
||||||
// A Buffer can turn a string or a []byte into an io.Reader.
|
// A Buffer can turn a string or a []byte into an io.Reader.
|
||||||
buf := NewBufferString("R29waGVycyBydWxlIQ==")
|
buf := NewBufferString("R29waGVycyBydWxlIQ==")
|
||||||
dec := base64.NewDecoder(base64.StdEncoding, buf)
|
dec := base64.NewDecoder(base64.StdEncoding, buf)
|
||||||
io.Copy(os.Stdout, dec)
|
io.Copy(os.Stdout, dec)
|
||||||
|
// Output: Gophers rule!
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,25 @@ func (pq *PriorityQueue) Pop() interface{} {
|
|||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
|
|
||||||
// 99:seven 88:five 77:zero 66:nine 55:three 44:two 33:six 22:one 11:four 00:eight
|
// update is not used by the example but shows how to take the top item from
|
||||||
|
// the queue, update its priority and value, and put it back.
|
||||||
|
func (pq *PriorityQueue) update(value string, priority int) {
|
||||||
|
item := heap.Pop(pq).(*Item)
|
||||||
|
item.value = value
|
||||||
|
item.priority = priority
|
||||||
|
heap.Push(pq, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
// changePriority is not used by the example but shows how to change the
|
||||||
|
// priority of an arbitrary item.
|
||||||
|
func (pq *PriorityQueue) changePriority(item *Item, priority int) {
|
||||||
|
heap.Remove(pq, item.index)
|
||||||
|
item.priority = priority
|
||||||
|
heap.Push(pq, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
// This example pushes 10 items into a PriorityQueue and takes them out in
|
||||||
|
// order of priority.
|
||||||
func Example() {
|
func Example() {
|
||||||
const nItem = 10
|
const nItem = 10
|
||||||
// Random priorities for the items (a permutation of 0..9, times 11)).
|
// Random priorities for the items (a permutation of 0..9, times 11)).
|
||||||
@ -82,21 +100,6 @@ func Example() {
|
|||||||
item := heap.Pop(&pq).(*Item)
|
item := heap.Pop(&pq).(*Item)
|
||||||
fmt.Printf("%.2d:%s ", item.priority, item.value)
|
fmt.Printf("%.2d:%s ", item.priority, item.value)
|
||||||
}
|
}
|
||||||
}
|
// Output:
|
||||||
|
// 99:seven 88:five 77:zero 66:nine 55:three 44:two 33:six 22:one 11:four 00:eight
|
||||||
// update is not used by the example but shows how to take the top item from the queue,
|
|
||||||
// update its priority and value, and put it back.
|
|
||||||
func (pq *PriorityQueue) update(value string, priority int) {
|
|
||||||
item := heap.Pop(pq).(*Item)
|
|
||||||
item.value = value
|
|
||||||
item.priority = priority
|
|
||||||
heap.Push(pq, item)
|
|
||||||
}
|
|
||||||
|
|
||||||
// changePriority is not used by the example but shows how to change the priority of an arbitrary
|
|
||||||
// item.
|
|
||||||
func (pq *PriorityQueue) changePriority(item *Item, priority int) {
|
|
||||||
heap.Remove(pq, item.index)
|
|
||||||
item.priority = priority
|
|
||||||
heap.Push(pq, item)
|
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 18 2d 44 54 fb 21 09 40
|
|
||||||
func ExampleWrite() {
|
func ExampleWrite() {
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
var pi float64 = math.Pi
|
var pi float64 = math.Pi
|
||||||
@ -20,9 +19,9 @@ func ExampleWrite() {
|
|||||||
fmt.Println("binary.Write failed:", err)
|
fmt.Println("binary.Write failed:", err)
|
||||||
}
|
}
|
||||||
fmt.Printf("% x", buf.Bytes())
|
fmt.Printf("% x", buf.Bytes())
|
||||||
|
// Output: 18 2d 44 54 fb 21 09 40
|
||||||
}
|
}
|
||||||
|
|
||||||
// cafebabe
|
|
||||||
func ExampleWrite_multi() {
|
func ExampleWrite_multi() {
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
var data = []interface{}{
|
var data = []interface{}{
|
||||||
@ -37,9 +36,9 @@ func ExampleWrite_multi() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Printf("%x", buf.Bytes())
|
fmt.Printf("%x", buf.Bytes())
|
||||||
|
// Output: cafebabe
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3.141592653589793
|
|
||||||
func ExampleRead() {
|
func ExampleRead() {
|
||||||
var pi float64
|
var pi float64
|
||||||
b := []byte{0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40}
|
b := []byte{0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40}
|
||||||
@ -49,4 +48,5 @@ func ExampleRead() {
|
|||||||
fmt.Println("binary.Read failed:", err)
|
fmt.Println("binary.Read failed:", err)
|
||||||
}
|
}
|
||||||
fmt.Print(pi)
|
fmt.Print(pi)
|
||||||
|
// Output: 3.141592653589793
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
// {"ID":1,"Name":"Reds","Colors":["Crimson","Red","Ruby","Maroon"]}
|
|
||||||
func ExampleMarshal() {
|
func ExampleMarshal() {
|
||||||
type ColorGroup struct {
|
type ColorGroup struct {
|
||||||
ID int
|
ID int
|
||||||
@ -27,9 +26,10 @@ func ExampleMarshal() {
|
|||||||
fmt.Println("error:", err)
|
fmt.Println("error:", err)
|
||||||
}
|
}
|
||||||
os.Stdout.Write(b)
|
os.Stdout.Write(b)
|
||||||
|
// Output:
|
||||||
|
// {"ID":1,"Name":"Reds","Colors":["Crimson","Red","Ruby","Maroon"]}
|
||||||
}
|
}
|
||||||
|
|
||||||
// [{Name:Platypus Order:Monotremata} {Name:Quoll Order:Dasyuromorphia}]
|
|
||||||
func ExampleUnmarshal() {
|
func ExampleUnmarshal() {
|
||||||
var jsonBlob = []byte(`[
|
var jsonBlob = []byte(`[
|
||||||
{"Name": "Platypus", "Order": "Monotremata"},
|
{"Name": "Platypus", "Order": "Monotremata"},
|
||||||
@ -45,4 +45,6 @@ func ExampleUnmarshal() {
|
|||||||
fmt.Println("error:", err)
|
fmt.Println("error:", err)
|
||||||
}
|
}
|
||||||
fmt.Printf("%+v", animals)
|
fmt.Printf("%+v", animals)
|
||||||
|
// Output:
|
||||||
|
// [{Name:Platypus Order:Monotremata} {Name:Quoll Order:Dasyuromorphia}]
|
||||||
}
|
}
|
||||||
|
@ -2,37 +2,37 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// Extract example functions from package ASTs.
|
// Extract example functions from file ASTs.
|
||||||
|
|
||||||
package doc
|
package ast
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go/ast"
|
|
||||||
"go/printer"
|
|
||||||
"go/token"
|
"go/token"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
"unicode"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Example struct {
|
type Example struct {
|
||||||
Name string // name of the item being demonstrated
|
Name string // name of the item being exemplified
|
||||||
Body *printer.CommentedNode // code
|
Code Node
|
||||||
Output string // expected output
|
Comments []*CommentGroup
|
||||||
|
Output string // expected output
|
||||||
}
|
}
|
||||||
|
|
||||||
func Examples(pkg *ast.Package) []*Example {
|
func Examples(files ...*File) []*Example {
|
||||||
var list []*Example
|
var list []*Example
|
||||||
for _, file := range pkg.Files {
|
for _, file := range files {
|
||||||
hasTests := false // file contains tests or benchmarks
|
hasTests := false // file contains tests or benchmarks
|
||||||
numDecl := 0 // number of non-import declarations in the file
|
numDecl := 0 // number of non-import declarations in the file
|
||||||
var flist []*Example
|
var flist []*Example
|
||||||
for _, decl := range file.Decls {
|
for _, decl := range file.Decls {
|
||||||
if g, ok := decl.(*ast.GenDecl); ok && g.Tok != token.IMPORT {
|
if g, ok := decl.(*GenDecl); ok && g.Tok != token.IMPORT {
|
||||||
numDecl++
|
numDecl++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
f, ok := decl.(*ast.FuncDecl)
|
f, ok := decl.(*FuncDecl)
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -46,25 +46,47 @@ func Examples(pkg *ast.Package) []*Example {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
flist = append(flist, &Example{
|
flist = append(flist, &Example{
|
||||||
Name: name[len("Example"):],
|
Name: name[len("Example"):],
|
||||||
Body: &printer.CommentedNode{
|
Code: f.Body,
|
||||||
Node: f.Body,
|
Comments: file.Comments,
|
||||||
Comments: file.Comments,
|
Output: exampleOutput(f, file.Comments),
|
||||||
},
|
|
||||||
Output: f.Doc.Text(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if !hasTests && numDecl > 1 && len(flist) == 1 {
|
if !hasTests && numDecl > 1 && len(flist) == 1 {
|
||||||
// If this file only has one example function, some
|
// If this file only has one example function, some
|
||||||
// other top-level declarations, and no tests or
|
// other top-level declarations, and no tests or
|
||||||
// benchmarks, use the whole file as the example.
|
// benchmarks, use the whole file as the example.
|
||||||
flist[0].Body.Node = file
|
flist[0].Code = file
|
||||||
}
|
}
|
||||||
list = append(list, flist...)
|
list = append(list, flist...)
|
||||||
}
|
}
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var outputPrefix = regexp.MustCompile(`(?i)^[[:space:]]*output:`)
|
||||||
|
|
||||||
|
func exampleOutput(fun *FuncDecl, comments []*CommentGroup) string {
|
||||||
|
// find the last comment in the function
|
||||||
|
var last *CommentGroup
|
||||||
|
for _, cg := range comments {
|
||||||
|
if cg.Pos() < fun.Pos() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if cg.End() > fun.End() {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
last = cg
|
||||||
|
}
|
||||||
|
if last != nil {
|
||||||
|
// test that it begins with the correct prefix
|
||||||
|
text := last.Text()
|
||||||
|
if loc := outputPrefix.FindStringIndex(text); loc != nil {
|
||||||
|
return strings.TrimSpace(text[loc[1]:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "" // no suitable comment found
|
||||||
|
}
|
||||||
|
|
||||||
// isTest tells whether name looks like a test, example, or benchmark.
|
// isTest tells whether name looks like a test, example, or benchmark.
|
||||||
// It is a Test (say) if there is a character after Test that is not a
|
// It is a Test (say) if there is a character after Test that is not a
|
||||||
// lower-case letter. (We don't want Testiness.)
|
// lower-case letter. (We don't want Testiness.)
|
@ -10,21 +10,20 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 3.142
|
|
||||||
func ExampleRat_SetString() {
|
func ExampleRat_SetString() {
|
||||||
r := new(big.Rat)
|
r := new(big.Rat)
|
||||||
r.SetString("355/113")
|
r.SetString("355/113")
|
||||||
fmt.Println(r.FloatString(3))
|
fmt.Println(r.FloatString(3))
|
||||||
|
// Output: 3.142
|
||||||
}
|
}
|
||||||
|
|
||||||
// 420
|
|
||||||
func ExampleInt_SetString() {
|
func ExampleInt_SetString() {
|
||||||
i := new(big.Int)
|
i := new(big.Int)
|
||||||
i.SetString("644", 8) // octal
|
i.SetString("644", 8) // octal
|
||||||
fmt.Println(i)
|
fmt.Println(i)
|
||||||
|
// Output: 420
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3/2
|
|
||||||
func ExampleRat_Scan() {
|
func ExampleRat_Scan() {
|
||||||
// The Scan function is rarely used directly;
|
// The Scan function is rarely used directly;
|
||||||
// the fmt package recognizes it as an implementation of fmt.Scanner.
|
// the fmt package recognizes it as an implementation of fmt.Scanner.
|
||||||
@ -35,9 +34,9 @@ func ExampleRat_Scan() {
|
|||||||
} else {
|
} else {
|
||||||
fmt.Println(r)
|
fmt.Println(r)
|
||||||
}
|
}
|
||||||
|
// Output: 3/2
|
||||||
}
|
}
|
||||||
|
|
||||||
// 18446744073709551617
|
|
||||||
func ExampleInt_Scan() {
|
func ExampleInt_Scan() {
|
||||||
// The Scan function is rarely used directly;
|
// The Scan function is rarely used directly;
|
||||||
// the fmt package recognizes it as an implementation of fmt.Scanner.
|
// the fmt package recognizes it as an implementation of fmt.Scanner.
|
||||||
@ -48,4 +47,5 @@ func ExampleInt_Scan() {
|
|||||||
} else {
|
} else {
|
||||||
fmt.Println(i)
|
fmt.Println(i)
|
||||||
}
|
}
|
||||||
|
// Output: 18446744073709551617
|
||||||
}
|
}
|
||||||
|
@ -9,17 +9,11 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
)
|
)
|
||||||
|
|
||||||
// b
|
|
||||||
func ExampleBase() {
|
func ExampleBase() {
|
||||||
fmt.Println(path.Base("/a/b"))
|
fmt.Println(path.Base("/a/b"))
|
||||||
|
// Output: b
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean("a/c") = "a/c"
|
|
||||||
// Clean("a//c") = "a/c"
|
|
||||||
// Clean("a/c/.") = "a/c"
|
|
||||||
// Clean("a/c/b/..") = "a/c"
|
|
||||||
// Clean("/../a/c") = "/a/c"
|
|
||||||
// Clean("/../a/b/../././/c") = "/a/c"
|
|
||||||
func ExampleClean() {
|
func ExampleClean() {
|
||||||
paths := []string{
|
paths := []string{
|
||||||
"a/c",
|
"a/c",
|
||||||
@ -33,29 +27,37 @@ func ExampleClean() {
|
|||||||
for _, p := range paths {
|
for _, p := range paths {
|
||||||
fmt.Printf("Clean(%q) = %q\n", p, path.Clean(p))
|
fmt.Printf("Clean(%q) = %q\n", p, path.Clean(p))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// Clean("a/c") = "a/c"
|
||||||
|
// Clean("a//c") = "a/c"
|
||||||
|
// Clean("a/c/.") = "a/c"
|
||||||
|
// Clean("a/c/b/..") = "a/c"
|
||||||
|
// Clean("/../a/c") = "/a/c"
|
||||||
|
// Clean("/../a/b/../././/c") = "/a/c"
|
||||||
}
|
}
|
||||||
|
|
||||||
// /a/b
|
|
||||||
func ExampleDir() {
|
func ExampleDir() {
|
||||||
fmt.Println(path.Dir("/a/b/c"))
|
fmt.Println(path.Dir("/a/b/c"))
|
||||||
|
// Output: /a/b
|
||||||
}
|
}
|
||||||
|
|
||||||
// .css
|
|
||||||
func ExampleExt() {
|
func ExampleExt() {
|
||||||
fmt.Println(path.Ext("/a/b/c/bar.css"))
|
fmt.Println(path.Ext("/a/b/c/bar.css"))
|
||||||
|
// Output: .css
|
||||||
}
|
}
|
||||||
|
|
||||||
// true
|
|
||||||
func ExampleIsAbs() {
|
func ExampleIsAbs() {
|
||||||
fmt.Println(path.IsAbs("/dev/null"))
|
fmt.Println(path.IsAbs("/dev/null"))
|
||||||
|
// Output: true
|
||||||
}
|
}
|
||||||
|
|
||||||
// a/b/c
|
|
||||||
func ExampleJoin() {
|
func ExampleJoin() {
|
||||||
fmt.Println(path.Join("a", "b", "c"))
|
fmt.Println(path.Join("a", "b", "c"))
|
||||||
|
// Output: a/b/c
|
||||||
}
|
}
|
||||||
|
|
||||||
// static/ myfile.css
|
|
||||||
func ExampleSplit() {
|
func ExampleSplit() {
|
||||||
fmt.Println(path.Split("static/myfile.css"))
|
fmt.Println(path.Split("static/myfile.css"))
|
||||||
|
// Output: static/ myfile.css
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,9 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
// [1 2 3 4 5 6]
|
|
||||||
func ExampleInts() {
|
func ExampleInts() {
|
||||||
s := []int{5, 2, 6, 3, 1, 4} // unsorted
|
s := []int{5, 2, 6, 3, 1, 4} // unsorted
|
||||||
sort.Ints(s)
|
sort.Ints(s)
|
||||||
fmt.Println(s)
|
fmt.Println(s)
|
||||||
|
// Output: [1 2 3 4 5 6]
|
||||||
}
|
}
|
||||||
|
@ -9,134 +9,142 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Fields are: ["foo" "bar" "baz"]
|
|
||||||
func ExampleFields() {
|
func ExampleFields() {
|
||||||
fmt.Printf("Fields are: %q", strings.Fields(" foo bar baz "))
|
fmt.Printf("Fields are: %q", strings.Fields(" foo bar baz "))
|
||||||
|
// Output: Fields are: ["foo" "bar" "baz"]
|
||||||
}
|
}
|
||||||
|
|
||||||
// true
|
|
||||||
// false
|
|
||||||
// true
|
|
||||||
// true
|
|
||||||
func ExampleContains() {
|
func ExampleContains() {
|
||||||
fmt.Println(strings.Contains("seafood", "foo"))
|
fmt.Println(strings.Contains("seafood", "foo"))
|
||||||
fmt.Println(strings.Contains("seafood", "bar"))
|
fmt.Println(strings.Contains("seafood", "bar"))
|
||||||
fmt.Println(strings.Contains("seafood", ""))
|
fmt.Println(strings.Contains("seafood", ""))
|
||||||
fmt.Println(strings.Contains("", ""))
|
fmt.Println(strings.Contains("", ""))
|
||||||
|
// Output:
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// true
|
||||||
|
// true
|
||||||
}
|
}
|
||||||
|
|
||||||
// false
|
|
||||||
// true
|
|
||||||
// false
|
|
||||||
// false
|
|
||||||
func ExampleContainsAny() {
|
func ExampleContainsAny() {
|
||||||
fmt.Println(strings.ContainsAny("team", "i"))
|
fmt.Println(strings.ContainsAny("team", "i"))
|
||||||
fmt.Println(strings.ContainsAny("failure", "u & i"))
|
fmt.Println(strings.ContainsAny("failure", "u & i"))
|
||||||
fmt.Println(strings.ContainsAny("foo", ""))
|
fmt.Println(strings.ContainsAny("foo", ""))
|
||||||
fmt.Println(strings.ContainsAny("", ""))
|
fmt.Println(strings.ContainsAny("", ""))
|
||||||
|
// Output:
|
||||||
|
// false
|
||||||
|
// true
|
||||||
|
// false
|
||||||
|
// false
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3
|
|
||||||
// 5
|
|
||||||
func ExampleCount() {
|
func ExampleCount() {
|
||||||
fmt.Println(strings.Count("cheese", "e"))
|
fmt.Println(strings.Count("cheese", "e"))
|
||||||
fmt.Println(strings.Count("five", "")) // before & after each rune
|
fmt.Println(strings.Count("five", "")) // before & after each rune
|
||||||
|
// Output:
|
||||||
|
// 3
|
||||||
|
// 5
|
||||||
}
|
}
|
||||||
|
|
||||||
// true
|
|
||||||
func ExampleEqualFold() {
|
func ExampleEqualFold() {
|
||||||
fmt.Println(strings.EqualFold("Go", "go"))
|
fmt.Println(strings.EqualFold("Go", "go"))
|
||||||
|
// Output: true
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4
|
|
||||||
// -1
|
|
||||||
func ExampleIndex() {
|
func ExampleIndex() {
|
||||||
fmt.Println(strings.Index("chicken", "ken"))
|
fmt.Println(strings.Index("chicken", "ken"))
|
||||||
fmt.Println(strings.Index("chicken", "dmr"))
|
fmt.Println(strings.Index("chicken", "dmr"))
|
||||||
|
// Output:
|
||||||
|
// 4
|
||||||
|
// -1
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4
|
|
||||||
// -1
|
|
||||||
func ExampleRune() {
|
func ExampleRune() {
|
||||||
fmt.Println(strings.IndexRune("chicken", 'k'))
|
fmt.Println(strings.IndexRune("chicken", 'k'))
|
||||||
fmt.Println(strings.IndexRune("chicken", 'd'))
|
fmt.Println(strings.IndexRune("chicken", 'd'))
|
||||||
|
// Output:
|
||||||
|
// 4
|
||||||
|
// -1
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0
|
|
||||||
// 3
|
|
||||||
// -1
|
|
||||||
func ExampleLastIndex() {
|
func ExampleLastIndex() {
|
||||||
fmt.Println(strings.Index("go gopher", "go"))
|
fmt.Println(strings.Index("go gopher", "go"))
|
||||||
fmt.Println(strings.LastIndex("go gopher", "go"))
|
fmt.Println(strings.LastIndex("go gopher", "go"))
|
||||||
fmt.Println(strings.LastIndex("go gopher", "rodent"))
|
fmt.Println(strings.LastIndex("go gopher", "rodent"))
|
||||||
|
// Output:
|
||||||
|
// 0
|
||||||
|
// 3
|
||||||
|
// -1
|
||||||
}
|
}
|
||||||
|
|
||||||
// foo, bar, baz
|
|
||||||
func ExampleJoin() {
|
func ExampleJoin() {
|
||||||
s := []string{"foo", "bar", "baz"}
|
s := []string{"foo", "bar", "baz"}
|
||||||
fmt.Println(strings.Join(s, ", "))
|
fmt.Println(strings.Join(s, ", "))
|
||||||
|
// Output: foo, bar, baz
|
||||||
}
|
}
|
||||||
|
|
||||||
// banana
|
|
||||||
func ExampleRepeat() {
|
func ExampleRepeat() {
|
||||||
fmt.Println("ba" + strings.Repeat("na", 2))
|
fmt.Println("ba" + strings.Repeat("na", 2))
|
||||||
|
// Output: banana
|
||||||
}
|
}
|
||||||
|
|
||||||
// oinky oinky oink
|
|
||||||
// moo moo moo
|
|
||||||
func ExampleReplace() {
|
func ExampleReplace() {
|
||||||
fmt.Println(strings.Replace("oink oink oink", "k", "ky", 2))
|
fmt.Println(strings.Replace("oink oink oink", "k", "ky", 2))
|
||||||
fmt.Println(strings.Replace("oink oink oink", "oink", "moo", -1))
|
fmt.Println(strings.Replace("oink oink oink", "oink", "moo", -1))
|
||||||
|
// Output:
|
||||||
|
// oinky oinky oink
|
||||||
|
// moo moo moo
|
||||||
}
|
}
|
||||||
|
|
||||||
// ["a" "b" "c"]
|
|
||||||
// ["" "man " "plan " "canal panama"]
|
|
||||||
// [" " "x" "y" "z" " "]
|
|
||||||
// [""]
|
|
||||||
func ExampleSplit() {
|
func ExampleSplit() {
|
||||||
fmt.Printf("%q\n", strings.Split("a,b,c", ","))
|
fmt.Printf("%q\n", strings.Split("a,b,c", ","))
|
||||||
fmt.Printf("%q\n", strings.Split("a man a plan a canal panama", "a "))
|
fmt.Printf("%q\n", strings.Split("a man a plan a canal panama", "a "))
|
||||||
fmt.Printf("%q\n", strings.Split(" xyz ", ""))
|
fmt.Printf("%q\n", strings.Split(" xyz ", ""))
|
||||||
fmt.Printf("%q\n", strings.Split("", "Bernardo O'Higgins"))
|
fmt.Printf("%q\n", strings.Split("", "Bernardo O'Higgins"))
|
||||||
|
// Output:
|
||||||
|
// ["a" "b" "c"]
|
||||||
|
// ["" "man " "plan " "canal panama"]
|
||||||
|
// [" " "x" "y" "z" " "]
|
||||||
|
// [""]
|
||||||
}
|
}
|
||||||
|
|
||||||
// ["a" "b,c"]
|
|
||||||
// [] (nil = true)
|
|
||||||
func ExampleSplitN() {
|
func ExampleSplitN() {
|
||||||
fmt.Printf("%q\n", strings.SplitN("a,b,c", ",", 2))
|
fmt.Printf("%q\n", strings.SplitN("a,b,c", ",", 2))
|
||||||
z := strings.SplitN("a,b,c", ",", 0)
|
z := strings.SplitN("a,b,c", ",", 0)
|
||||||
fmt.Printf("%q (nil = %v)\n", z, z == nil)
|
fmt.Printf("%q (nil = %v)\n", z, z == nil)
|
||||||
|
// Output:
|
||||||
|
// ["a" "b,c"]
|
||||||
|
// [] (nil = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ["a," "b," "c"]
|
|
||||||
func ExampleSplitAfter() {
|
func ExampleSplitAfter() {
|
||||||
fmt.Printf("%q\n", strings.SplitAfter("a,b,c", ","))
|
fmt.Printf("%q\n", strings.SplitAfter("a,b,c", ","))
|
||||||
|
// Output: ["a," "b," "c"]
|
||||||
}
|
}
|
||||||
|
|
||||||
// ["a," "b,c"]
|
|
||||||
func ExampleSplitAfterN() {
|
func ExampleSplitAfterN() {
|
||||||
fmt.Printf("%q\n", strings.SplitAfterN("a,b,c", ",", 2))
|
fmt.Printf("%q\n", strings.SplitAfterN("a,b,c", ",", 2))
|
||||||
|
// Output: ["a," "b,c"]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Her Royal Highness
|
|
||||||
func ExampleTitle() {
|
func ExampleTitle() {
|
||||||
fmt.Println(strings.Title("her royal highness"))
|
fmt.Println(strings.Title("her royal highness"))
|
||||||
|
// Output: Her Royal Highness
|
||||||
}
|
}
|
||||||
|
|
||||||
// LOUD NOISES
|
|
||||||
// ХЛЕБ
|
|
||||||
func ExampleToTitle() {
|
func ExampleToTitle() {
|
||||||
fmt.Println(strings.ToTitle("loud noises"))
|
fmt.Println(strings.ToTitle("loud noises"))
|
||||||
fmt.Println(strings.ToTitle("хлеб"))
|
fmt.Println(strings.ToTitle("хлеб"))
|
||||||
|
// Output:
|
||||||
|
// LOUD NOISES
|
||||||
|
// ХЛЕБ
|
||||||
}
|
}
|
||||||
|
|
||||||
// [Achtung]
|
|
||||||
func ExampleTrim() {
|
func ExampleTrim() {
|
||||||
fmt.Printf("[%s]", strings.Trim(" !!! Achtung !!! ", "! "))
|
fmt.Printf("[%q]", strings.Trim(" !!! Achtung !!! ", "! "))
|
||||||
|
// Output: ["Achtung"]
|
||||||
}
|
}
|
||||||
|
|
||||||
// 'Gjnf oevyyvt naq gur fyvgul tbcure...
|
|
||||||
func ExampleMap() {
|
func ExampleMap() {
|
||||||
rot13 := func(r rune) rune {
|
rot13 := func(r rune) rune {
|
||||||
switch {
|
switch {
|
||||||
@ -148,25 +156,26 @@ func ExampleMap() {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
fmt.Println(strings.Map(rot13, "'Twas brillig and the slithy gopher..."))
|
fmt.Println(strings.Map(rot13, "'Twas brillig and the slithy gopher..."))
|
||||||
|
// Output: 'Gjnf oevyyvt naq gur fyvgul tbcure...
|
||||||
}
|
}
|
||||||
|
|
||||||
// a lone gopher
|
|
||||||
func ExampleTrimSpace() {
|
func ExampleTrimSpace() {
|
||||||
fmt.Println(strings.TrimSpace(" \t\n a lone gopher \n\t\r\n"))
|
fmt.Println(strings.TrimSpace(" \t\n a lone gopher \n\t\r\n"))
|
||||||
|
// Output: a lone gopher
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is <b>HTML</b>!
|
|
||||||
func ExampleNewReplacer() {
|
func ExampleNewReplacer() {
|
||||||
r := strings.NewReplacer("<", "<", ">", ">")
|
r := strings.NewReplacer("<", "<", ">", ">")
|
||||||
fmt.Println(r.Replace("This is <b>HTML</b>!"))
|
fmt.Println(r.Replace("This is <b>HTML</b>!"))
|
||||||
|
// Output: This is <b>HTML</b>!
|
||||||
}
|
}
|
||||||
|
|
||||||
// GOPHER
|
|
||||||
func ExampleToUpper() {
|
func ExampleToUpper() {
|
||||||
fmt.Println(strings.ToUpper("Gopher"))
|
fmt.Println(strings.ToUpper("Gopher"))
|
||||||
|
// Output: GOPHER
|
||||||
}
|
}
|
||||||
|
|
||||||
// gopher
|
|
||||||
func ExampleToLower() {
|
func ExampleToLower() {
|
||||||
fmt.Println(strings.ToLower("Gopher"))
|
fmt.Println(strings.ToLower("Gopher"))
|
||||||
|
// Output: gopher
|
||||||
}
|
}
|
||||||
|
@ -38,16 +38,25 @@
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// The package also runs and verifies example code. Example functions
|
// The package also runs and verifies example code. Example functions may
|
||||||
// include an introductory comment that is compared with the standard output
|
// include a concluding comment that begins with "Output:" and is compared with
|
||||||
// of the function when the tests are run, as in this example of an example:
|
// the standard output of the function when the tests are run, as in these
|
||||||
|
// examples of an example:
|
||||||
//
|
//
|
||||||
// // hello
|
|
||||||
// func ExampleHello() {
|
// func ExampleHello() {
|
||||||
// fmt.Println("hello")
|
// fmt.Println("hello")
|
||||||
|
// // Output: hello
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// Example functions without comments are compiled but not executed.
|
// func ExampleSalutations() {
|
||||||
|
// fmt.Println("hello, and")
|
||||||
|
// fmt.Println("goodbye")
|
||||||
|
// // Output:
|
||||||
|
// // hello, and
|
||||||
|
// // goodbye
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Example functions without output comments are compiled but not executed.
|
||||||
//
|
//
|
||||||
// The naming convention to declare examples for a function F, a type T and
|
// The naming convention to declare examples for a function F, a type T and
|
||||||
// method M on type T are:
|
// method M on type T are:
|
||||||
|
@ -10,28 +10,6 @@ import (
|
|||||||
"text/template"
|
"text/template"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Dear Aunt Mildred,
|
|
||||||
//
|
|
||||||
// It was a pleasure to see you at the wedding.
|
|
||||||
// Thank you for the lovely bone china tea set.
|
|
||||||
//
|
|
||||||
// Best wishes,
|
|
||||||
// Josie
|
|
||||||
//
|
|
||||||
// Dear Uncle John,
|
|
||||||
//
|
|
||||||
// It is a shame you couldn't make it to the wedding.
|
|
||||||
// Thank you for the lovely moleskin pants.
|
|
||||||
//
|
|
||||||
// Best wishes,
|
|
||||||
// Josie
|
|
||||||
//
|
|
||||||
// Dear Cousin Rodney,
|
|
||||||
//
|
|
||||||
// It is a shame you couldn't make it to the wedding.
|
|
||||||
//
|
|
||||||
// Best wishes,
|
|
||||||
// Josie
|
|
||||||
func ExampleTemplate() {
|
func ExampleTemplate() {
|
||||||
// Define a template.
|
// Define a template.
|
||||||
const letter = `
|
const letter = `
|
||||||
@ -66,4 +44,28 @@ Josie
|
|||||||
log.Println("executing template:", err)
|
log.Println("executing template:", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// Dear Aunt Mildred,
|
||||||
|
//
|
||||||
|
// It was a pleasure to see you at the wedding.
|
||||||
|
// Thank you for the lovely bone china tea set.
|
||||||
|
//
|
||||||
|
// Best wishes,
|
||||||
|
// Josie
|
||||||
|
//
|
||||||
|
// Dear Uncle John,
|
||||||
|
//
|
||||||
|
// It is a shame you couldn't make it to the wedding.
|
||||||
|
// Thank you for the lovely moleskin pants.
|
||||||
|
//
|
||||||
|
// Best wishes,
|
||||||
|
// Josie
|
||||||
|
//
|
||||||
|
// Dear Cousin Rodney,
|
||||||
|
//
|
||||||
|
// It is a shame you couldn't make it to the wedding.
|
||||||
|
//
|
||||||
|
// Best wishes,
|
||||||
|
// Josie
|
||||||
}
|
}
|
||||||
|
@ -51,8 +51,8 @@ func ExampleMonth() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Go launched at 2009-11-10 15:00:00 -0800 PST
|
|
||||||
func ExampleDate() {
|
func ExampleDate() {
|
||||||
t := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
|
t := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
|
||||||
fmt.Printf("Go launched at %s\n", t.Local())
|
fmt.Printf("Go launched at %s\n", t.Local())
|
||||||
|
// Output: Go launched at 2009-11-10 15:00:00 -0800 PST
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user