Commit 18b21c72 authored by Rob Pike's avatar Rob Pike

effective go: extract and test a couple more examples.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/4937045
parent 93134e06
...@@ -1622,11 +1622,12 @@ enumerator. Since <code>iota</code> can be part of an expression and ...@@ -1622,11 +1622,12 @@ enumerator. Since <code>iota</code> can be part of an expression and
expressions can be implicitly repeated, it is easy to build intricate expressions can be implicitly repeated, it is easy to build intricate
sets of values. sets of values.
</p> </p>
<pre> <pre><!--{{code "progs/eff_bytesize.go" `/^type ByteSize/` `/^\)/`}}
type ByteSize float64 -->type ByteSize float64
const ( const (
_ = iota // ignore first value by assigning to blank identifier _ = iota // ignore first value by assigning to blank identifier
KB ByteSize = 1&lt;&lt;(10*iota) KB ByteSize = 1 &lt;&lt; (10 * iota)
MB MB
GB GB
TB TB
...@@ -1641,27 +1642,27 @@ The ability to attach a method such as <code>String</code> to a ...@@ -1641,27 +1642,27 @@ The ability to attach a method such as <code>String</code> to a
type makes it possible for such values to format themselves type makes it possible for such values to format themselves
automatically for printing, even as part of a general type. automatically for printing, even as part of a general type.
</p> </p>
<pre> <pre><!--{{code "progs/eff_bytesize.go" `/^func.*ByteSize.*String/` `/^}/`}}
func (b ByteSize) String() string { -->func (b ByteSize) String() string {
switch { switch {
case b &gt;= YB: case b &gt;= YB:
return fmt.Sprintf("%.2fYB", float64(b/YB)) return fmt.Sprintf(&#34;%.2fYB&#34;, float64(b/YB))
case b &gt;= ZB: case b &gt;= ZB:
return fmt.Sprintf("%.2fZB", float64(b/ZB)) return fmt.Sprintf(&#34;%.2fZB&#34;, float64(b/ZB))
case b &gt;= EB: case b &gt;= EB:
return fmt.Sprintf("%.2fEB", float64(b/EB)) return fmt.Sprintf(&#34;%.2fEB&#34;, float64(b/EB))
case b &gt;= PB: case b &gt;= PB:
return fmt.Sprintf("%.2fPB", float64(b/PB)) return fmt.Sprintf(&#34;%.2fPB&#34;, float64(b/PB))
case b &gt;= TB: case b &gt;= TB:
return fmt.Sprintf("%.2fTB", float64(b/TB)) return fmt.Sprintf(&#34;%.2fTB&#34;, float64(b/TB))
case b &gt;= GB: case b &gt;= GB:
return fmt.Sprintf("%.2fGB", float64(b/GB)) return fmt.Sprintf(&#34;%.2fGB&#34;, float64(b/GB))
case b &gt;= MB: case b &gt;= MB:
return fmt.Sprintf("%.2fMB", float64(b/MB)) return fmt.Sprintf(&#34;%.2fMB&#34;, float64(b/MB))
case b &gt;= KB: case b &gt;= KB:
return fmt.Sprintf("%.2fKB", float64(b/KB)) return fmt.Sprintf(&#34;%.2fKB&#34;, float64(b/KB))
} }
return fmt.Sprintf("%.2fB", float64(b)) return fmt.Sprintf(&#34;%.2fB&#34;, float64(b))
} }
</pre> </pre>
<p> <p>
...@@ -1812,8 +1813,8 @@ by the routines in package <code>sort</code> if it implements ...@@ -1812,8 +1813,8 @@ by the routines in package <code>sort</code> if it implements
and it could also have a custom formatter. and it could also have a custom formatter.
In this contrived example <code>Sequence</code> satisfies both. In this contrived example <code>Sequence</code> satisfies both.
</p> </p>
<pre> <pre><!--{{code "progs/eff_sequence.go" `/^type/` "$"}}
type Sequence []int -->type Sequence []int
// Methods required by sort.Interface. // Methods required by sort.Interface.
func (s Sequence) Len() int { func (s Sequence) Len() int {
...@@ -1829,14 +1830,14 @@ func (s Sequence) Swap(i, j int) { ...@@ -1829,14 +1830,14 @@ func (s Sequence) Swap(i, j int) {
// Method for printing - sorts the elements before printing. // Method for printing - sorts the elements before printing.
func (s Sequence) String() string { func (s Sequence) String() string {
sort.Sort(s) sort.Sort(s)
str := "[" str := &#34;[&#34;
for i, elem := range s { for i, elem := range s {
if i &gt; 0 { if i &gt; 0 {
str += " " str += &#34; &#34;
} }
str += fmt.Sprint(elem) str += fmt.Sprint(elem)
} }
return str + "]" return str + &#34;]&#34;
} }
</pre> </pre>
......
...@@ -1622,48 +1622,13 @@ enumerator. Since <code>iota</code> can be part of an expression and ...@@ -1622,48 +1622,13 @@ enumerator. Since <code>iota</code> can be part of an expression and
expressions can be implicitly repeated, it is easy to build intricate expressions can be implicitly repeated, it is easy to build intricate
sets of values. sets of values.
</p> </p>
<pre> {{code "progs/eff_bytesize.go" `/^type ByteSize/` `/^\)/`}}
type ByteSize float64
const (
_ = iota // ignore first value by assigning to blank identifier
KB ByteSize = 1&lt;&lt;(10*iota)
MB
GB
TB
PB
EB
ZB
YB
)
</pre>
<p> <p>
The ability to attach a method such as <code>String</code> to a The ability to attach a method such as <code>String</code> to a
type makes it possible for such values to format themselves type makes it possible for such values to format themselves
automatically for printing, even as part of a general type. automatically for printing, even as part of a general type.
</p> </p>
<pre> {{code "progs/eff_bytesize.go" `/^func.*ByteSize.*String/` `/^}/`}}
func (b ByteSize) String() string {
switch {
case b &gt;= YB:
return fmt.Sprintf("%.2fYB", float64(b/YB))
case b &gt;= ZB:
return fmt.Sprintf("%.2fZB", float64(b/ZB))
case b &gt;= EB:
return fmt.Sprintf("%.2fEB", float64(b/EB))
case b &gt;= PB:
return fmt.Sprintf("%.2fPB", float64(b/PB))
case b &gt;= TB:
return fmt.Sprintf("%.2fTB", float64(b/TB))
case b &gt;= GB:
return fmt.Sprintf("%.2fGB", float64(b/GB))
case b &gt;= MB:
return fmt.Sprintf("%.2fMB", float64(b/MB))
case b &gt;= KB:
return fmt.Sprintf("%.2fKB", float64(b/KB))
}
return fmt.Sprintf("%.2fB", float64(b))
}
</pre>
<p> <p>
(The <code>float64</code> conversions prevent <code>Sprintf</code> (The <code>float64</code> conversions prevent <code>Sprintf</code>
from recurring back through the <code>String</code> method for from recurring back through the <code>String</code> method for
...@@ -1812,33 +1777,7 @@ by the routines in package <code>sort</code> if it implements ...@@ -1812,33 +1777,7 @@ by the routines in package <code>sort</code> if it implements
and it could also have a custom formatter. and it could also have a custom formatter.
In this contrived example <code>Sequence</code> satisfies both. In this contrived example <code>Sequence</code> satisfies both.
</p> </p>
<pre> {{code "progs/eff_sequence.go" `/^type/` "$"}}
type Sequence []int
// Methods required by sort.Interface.
func (s Sequence) Len() int {
return len(s)
}
func (s Sequence) Less(i, j int) bool {
return s[i] &lt; s[j]
}
func (s Sequence) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
// Method for printing - sorts the elements before printing.
func (s Sequence) String() string {
sort.Sort(s)
str := "["
for i, elem := range s {
if i &gt; 0 {
str += " "
}
str += fmt.Sprint(elem)
}
return str + "]"
}
</pre>
<h3 id="conversions">Conversions</h3> <h3 id="conversions">Conversions</h3>
......
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import "fmt"
type ByteSize float64
const (
_ = iota // ignore first value by assigning to blank identifier
KB ByteSize = 1 << (10 * iota)
MB
GB
TB
PB
EB
ZB
YB
)
func (b ByteSize) String() string {
switch {
case b >= YB:
return fmt.Sprintf("%.2fYB", float64(b/YB))
case b >= ZB:
return fmt.Sprintf("%.2fZB", float64(b/ZB))
case b >= EB:
return fmt.Sprintf("%.2fEB", float64(b/EB))
case b >= PB:
return fmt.Sprintf("%.2fPB", float64(b/PB))
case b >= TB:
return fmt.Sprintf("%.2fTB", float64(b/TB))
case b >= GB:
return fmt.Sprintf("%.2fGB", float64(b/GB))
case b >= MB:
return fmt.Sprintf("%.2fMB", float64(b/MB))
case b >= KB:
return fmt.Sprintf("%.2fKB", float64(b/KB))
}
return fmt.Sprintf("%.2fB", float64(b))
}
func main() {
fmt.Println(YB, ByteSize(1e13))
}
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"fmt"
"sort"
)
func main() {
seq := Sequence{6, 2, -1, 44, 16}
sort.Sort(seq)
fmt.Println(seq)
}
type Sequence []int
// Methods required by sort.Interface.
func (s Sequence) Len() int {
return len(s)
}
func (s Sequence) Less(i, j int) bool {
return s[i] < s[j]
}
func (s Sequence) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
// Method for printing - sorts the elements before printing.
func (s Sequence) String() string {
sort.Sort(s)
str := "["
for i, elem := range s {
if i > 0 {
str += " "
}
str += fmt.Sprint(elem)
}
return str + "]"
}
...@@ -35,7 +35,9 @@ for i in \ ...@@ -35,7 +35,9 @@ for i in \
sieve1.go \ sieve1.go \
server1.go \ server1.go \
strings.go \ strings.go \
eff_bytesize.go\
eff_qr.go \ eff_qr.go \
eff_sequence.go\
; do ; do
$GC $i $GC $i
done done
...@@ -83,4 +85,7 @@ testitpipe sieve "sed 10q" "2 3 5 7 11 13 17 19 23 29" ...@@ -83,4 +85,7 @@ testitpipe sieve "sed 10q" "2 3 5 7 11 13 17 19 23 29"
$GC server.go $GC server.go
testit server1 "" "" testit server1 "" ""
testit eff_bytesize "" "1.00YB 9.09TB"
testit eff_sequence "" "[-1 2 6 16 44]"
rm -f $O.out *.$O rm -f $O.out *.$O
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment