From 4074795e151813f303d5500d255901c6a3a796ef Mon Sep 17 00:00:00 2001
From: Rob Pike range
clause can
manage the loop.
-var m map[string]int +for key, value := range oldMap { + newMap[key] = value +} ++ +
+If you only need the first item in the range (the key or index), drop the second: +
++for key := range m { + if expired(key) { + delete(m, key) + } +} ++ +
+If you only need the second item in the range (the value), use the blank identifier, an underscore, to discard the first: +
+sum := 0 -for _, value := range m { // key is unused +for _, value := range array { sum += value }@@ -709,7 +728,7 @@ func shouldEscape(c byte) bool { Here's a comparison routine for byte arrays that uses two
switch
statements:
-// Compare returns an integer comparing the two byte arrays +// Compare returns an integer comparing the two byte arrays, // lexicographically. // The result will be 0 if a == b, -1 if a < b, and +1 if a > b func Compare(a, b []byte) int { @@ -1003,7 +1022,7 @@ but the rules are simple. Let's talk aboutnew
first. It's a built-in function that allocates memory, but unlike its namesakes in some other languages it does not initialize the memory, -it only zeroes it. +it only zeros it. That is,new(T)
allocates zeroed storage for a new item of typeT
and returns its address, a value of type*T
. @@ -1265,7 +1284,7 @@ any. To read into the first 32 bytes of a larger buffer
Such slicing is common and efficient. In fact, leaving efficiency aside for -the moment, this snippet would also read the first 32 bytes of the buffer. +the moment, the following snippet would also read the first 32 bytes of the buffer.
var n int @@ -1407,7 +1426,7 @@ func offset(tz string) int {
To test for presence in the map without worrying about the actual value,
-you can use the blank identifier, a simple underscore (_
).
+you can use the blank identifier (_
).
The blank identifier can be assigned or declared with any value of any type, with the
value discarded harmlessly. For testing just presence in a map, use the blank
identifier in place of the usual variable for the value.
@@ -1697,13 +1716,20 @@ automatically for printing, even as part of a general type.
-(The float64
conversions prevent Sprintf
-from recurring back through the String
method for
-ByteSize
.)
The expression YB
prints as 1.00YB
,
while ByteSize(1e13)
prints as 9.09TB
.
+Note that it's fine to call Sprintf
and friends in the
+implementation of String
methods, but beware of
+recurring into the String
method through the nested
+Sprintf
call using a string format
+(%s
, %q
, %v
, %x
or %X
).
+The ByteSize
implementation of String
is safe
+because it calls Sprintf
with %f
.
+
@@ -2520,8 +2546,8 @@ system, and there's not a mutex in sight.
Another application of these ideas is to parallelize a calculation across multiple CPU cores. If the calculation can be broken into -separate pieces, it can be parallelized, with a channel to signal -when each piece completes. +separate pieces that can execute independently, it can be parallelized, +with a channel to signal when each piece completes.
Let's say we have an expensive operation to perform on a vector of items, @@ -2563,7 +2589,7 @@ func (v Vector) DoAll(u Vector) {
-The current implementation of gc
(6g
, etc.)
+The current implementation of the Go runtime
will not parallelize this code by default.
It dedicates only a single core to user-level processing. An
arbitrary number of goroutines can be blocked in system calls, but
@@ -2989,7 +3015,7 @@ If this is too quick an explanation, see the docum
for the template package for a more thorough discussion.
-And there you have it: a useful webserver in a few lines of code plus some +And there you have it: a useful web server in a few lines of code plus some data-driven HTML text. Go is powerful enough to make a lot happen in a few lines.
diff --git a/doc/progs/eff_bytesize.go b/doc/progs/eff_bytesize.go index bcfde1a5a35..b45961114dd 100644 --- a/doc/progs/eff_bytesize.go +++ b/doc/progs/eff_bytesize.go @@ -23,23 +23,23 @@ const ( func (b ByteSize) String() string { switch { case b >= YB: - return fmt.Sprintf("%.2fYB", float64(b/YB)) + return fmt.Sprintf("%.2fYB", b/YB) case b >= ZB: - return fmt.Sprintf("%.2fZB", float64(b/ZB)) + return fmt.Sprintf("%.2fZB", b/ZB) case b >= EB: - return fmt.Sprintf("%.2fEB", float64(b/EB)) + return fmt.Sprintf("%.2fEB", b/EB) case b >= PB: - return fmt.Sprintf("%.2fPB", float64(b/PB)) + return fmt.Sprintf("%.2fPB", b/PB) case b >= TB: - return fmt.Sprintf("%.2fTB", float64(b/TB)) + return fmt.Sprintf("%.2fTB", b/TB) case b >= GB: - return fmt.Sprintf("%.2fGB", float64(b/GB)) + return fmt.Sprintf("%.2fGB", b/GB) case b >= MB: - return fmt.Sprintf("%.2fMB", float64(b/MB)) + return fmt.Sprintf("%.2fMB", b/MB) case b >= KB: - return fmt.Sprintf("%.2fKB", float64(b/KB)) + return fmt.Sprintf("%.2fKB", b/KB) } - return fmt.Sprintf("%.2fB", float64(b)) + return fmt.Sprintf("%.2fB", b) } func main() {