]> Cypherpunks repositories - gostls13.git/commitdiff
fmt: add a package-level example illustrating basic formats
authorRob Pike <r@golang.org>
Fri, 21 Sep 2018 00:48:05 +0000 (10:48 +1000)
committerRob Pike <r@golang.org>
Mon, 24 Sep 2018 21:02:01 +0000 (21:02 +0000)
There is much left out hereβ€”the space of possibilities is very
largeβ€”but this example shows all that most programmers will need
to know for most printing problems.

Update #27554.

Change-Id: Ib6ae651d5c3720cf7fe1a05ffd0859a5b56a9157
Reviewed-on: https://go-review.googlesource.com/136616
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/fmt/example_test.go

index 0ec374d217213c327815c819d78edba2b2ef7a06..bf9a6078f18c7e8b74e43ee5bc17b590873dc6bb 100644 (file)
@@ -7,8 +7,10 @@ package fmt_test
 import (
        "fmt"
        "io"
+       "math"
        "os"
        "strings"
+       "time"
 )
 
 // The Errorf function lets us use formatting features
@@ -131,3 +133,150 @@ func ExampleSprint() {
        // thereare99gophers
        // 17
 }
+
+// These examples demonstrate the basics of printing using a format string. Printf,
+// Sprintf, and Fprintf all take a format string that specifies how to format the
+// subsequent arguments. For example, %d (we call that a 'verb') says to print the
+// corresponding argument, which must be an integer (or something containing an
+// integer, such as a slice of ints) in decimal. The verb %v ('v' for 'value')
+// always formats the argument in its default form, just how Print or Println would
+// show it. The special verb %T ('T' for 'Type') prints the type of the argument
+// rather than its value. The examples are not exhaustive; see the package comment
+// for all the details.
+func Example_formats() {
+       // A basic set of examples showing that %v is the default format, in this
+       // case decimal for integers, which can be explicitly requested with %d;
+       // the output is just what Println generates.
+       integer := 23
+       // Each of these prints "23" (without the quotes).
+       fmt.Println(integer)
+       fmt.Printf("%v\n", integer)
+       fmt.Printf("%d\n", integer)
+
+       // The special verb %T shows the type of an item rather than its value.
+       fmt.Printf("%T %T\n", integer, &integer)
+       // Result: int *int
+
+       // Println(x) is the same as Printf("%v\n", x) so we will use only Printf
+       // in the following examples. Each one demonstrates how to format values of
+       // a particular type, such as integers or strings. We start each format
+       // string with %v to show the default output and follow that with one or
+       // more custom formats.
+
+       // Booleans print as "true" or "false" with %v or %t.
+       truth := true
+       fmt.Printf("%v %t\n", truth, truth)
+       // Result: true true
+
+       // Integers print as decimals with %v and %d,
+       // or in hex with %x, octal with %o, or binary with %b.
+       answer := 42
+       fmt.Printf("%v %d %x %o %b\n", answer, answer, answer, answer, answer)
+       // Result: 42 42 2a 52 101010
+
+       // Floats have multiple formats: %v and %g print a compact representation,
+       // while %f prints a decimal point and %e uses exponential notation. The
+       // format %6.2f used here shows how to set the width and precision to
+       // control the appearance of a floating-point value. In this instance, 6 is
+       // the total width of the printed text for the value (note the extra spaces
+       // in the output) and 2 is the number of decimal places to show.
+       pi := math.Pi
+       fmt.Printf("%v %g %.2f (%6.2f) %e\n", pi, pi, pi, pi, pi)
+       // Result: 3.141592653589793 3.141592653589793 3.14 (  3.14) 3.141593e+00
+
+       // Complex numbers format as parenthesized pairs of floats, with an 'i'
+       // after the imaginary part.
+       point := 110.7 + 22.5i
+       fmt.Printf("%v %g %.2f %.2e\n", point, point, point, point)
+       // Result: (110.7+22.5i) (110.7+22.5i) (110.70+22.50i) (1.11e+02+2.25e+01i)
+
+       // Runes are integers but when printed with %c show the character with that
+       // Unicode value. The %q verb shows them as quoted characters, %U as a
+       // hex Unicode code point, and %#U as both a code point and a quoted
+       // printable form if the rune is printable.
+       smile := 'πŸ˜€'
+       fmt.Printf("%v %d %c %q %U %#U\n", smile, smile, smile, smile, smile, smile)
+       // Result: 128512 128512 πŸ˜€ 'πŸ˜€' U+1F600 U+1F600 'πŸ˜€'
+
+       // Strings are formatted with %v and %s as-is, with %q as quoted strings,
+       // and %#q as backquoted strings.
+       placeholders := `foo "bar"`
+       fmt.Printf("%v %s %q %#q\n", placeholders, placeholders, placeholders, placeholders)
+       // Result: foo "bar" foo "bar" "foo \"bar\"" `foo "bar"`
+
+       // Maps formatted with %v show keys and values in their default formats.
+       // The %#v form (the # is called a "flag" in this context) shows the map in
+       // the Go source format.
+       isLegume := map[string]bool{
+               "peanut": true,
+               // TODO: Include this line when maps are printed in deterministic order.
+               // See Issue #21095
+               // "dachshund": false,
+       }
+       fmt.Printf("%v %#v\n", isLegume, isLegume)
+       // Result: map[peanut:true] map[string]bool{"peanut":true}
+
+       // Structs formatted with %v show field values in their default formats.
+       // The %+v form shows the fields by name, while %#v formats the struct in
+       // Go source format.
+       person := struct {
+               Name string
+               Age  int
+       }{"Kim", 22}
+       fmt.Printf("%v %+v %#v\n", person, person, person)
+       // Result: {Kim 22} {Name:Kim Age:22} struct { Name string; Age int }{Name:"Kim", Age:22}
+
+       // The default format for a pointer shows the underlying value preceded by
+       // an ampersand. The %p verb prints the pointer value in hex. We use a
+       // typed nil for the argument to %p here because the value of any non-nil
+       // pointer would change from run to run; run the commented-out Printf
+       // call yourself to see.
+       pointer := &person
+       fmt.Printf("%v %p\n", pointer, (*int)(nil))
+       // Result: &{Kim 22} 0x0
+       // fmt.Printf("%v %p\n", pointer, pointer)
+       // Result: &{Kim 22} 0x010203 // See comment above.
+
+       // Arrays and slices are formatted by applying the format to each element.
+       greats := [5]string{"Katano", "Kobayashi", "Kurosawa", "Miyazaki", "Ozu"}
+       fmt.Printf("%v %q\n", greats, greats)
+       // Result: [Katano Kobayashi Kurosawa Miyazaki Ozu] ["Katano" "Kobayashi" "Kurosawa" "Miyazaki" "Ozu"]
+
+       kGreats := greats[:3]
+       fmt.Printf("%v %q %#v\n", kGreats, kGreats, kGreats)
+       // Result: [Katano Kobayashi Kurosawa] ["Katano" "Kobayashi" "Kurosawa"] []string{"Katano", "Kobayashi", "Kurosawa"}
+
+       // Byte slices are special. Integer verbs like %d print the elements in
+       // that format. The %s and %q forms treat the slice like a string. The %x
+       // verb has a special form with the space flag that puts a space between
+       // the bytes.
+       cmd := []byte("a⌘")
+       fmt.Printf("%v %d %s %q %x % x\n", cmd, cmd, cmd, cmd, cmd, cmd)
+       // Result: [97 226 140 152] [97 226 140 152] a⌘ "a⌘" 61e28c98 61 e2 8c 98
+
+       // Types that implement Stringer are printed the same as strings. Because
+       // Stringers return a string, we can print them using a string-specific
+       // verb such as %q.
+       now := time.Unix(123456789, 0).UTC() // time.Time implements fmt.Stringer.
+       fmt.Printf("%v %q\n", now, now)
+       // Result: 1973-11-29 21:33:09 +0000 UTC "1973-11-29 21:33:09 +0000 UTC"
+
+       // Output:
+       // 23
+       // 23
+       // 23
+       // int *int
+       // true true
+       // 42 42 2a 52 101010
+       // 3.141592653589793 3.141592653589793 3.14 (  3.14) 3.141593e+00
+       // (110.7+22.5i) (110.7+22.5i) (110.70+22.50i) (1.11e+02+2.25e+01i)
+       // 128512 128512 πŸ˜€ 'πŸ˜€' U+1F600 U+1F600 'πŸ˜€'
+       // foo "bar" foo "bar" "foo \"bar\"" `foo "bar"`
+       // map[peanut:true] map[string]bool{"peanut":true}
+       // {Kim 22} {Name:Kim Age:22} struct { Name string; Age int }{Name:"Kim", Age:22}
+       // &{Kim 22} 0x0
+       // [Katano Kobayashi Kurosawa Miyazaki Ozu] ["Katano" "Kobayashi" "Kurosawa" "Miyazaki" "Ozu"]
+       // [Katano Kobayashi Kurosawa] ["Katano" "Kobayashi" "Kurosawa"] []string{"Katano", "Kobayashi", "Kurosawa"}
+       // [97 226 140 152] [97 226 140 152] a⌘ "a⌘" 61e28c98 61 e2 8c 98
+       // 1973-11-29 21:33:09 +0000 UTC "1973-11-29 21:33:09 +0000 UTC"
+}