Commit 781462dc authored by Rob Pike's avatar Rob Pike

doc/tutorial: update for slice changes.

Awaiting the lower-bound change before checkin.

Fixes #1067.

R=rsc, iant, gri
CC=golang-dev
https://golang.org/cl/2105043
parent 0eb0afde
...@@ -286,14 +286,15 @@ In Go, since arrays are values, it's meaningful (and useful) to talk ...@@ -286,14 +286,15 @@ In Go, since arrays are values, it's meaningful (and useful) to talk
about pointers to arrays. about pointers to arrays.
<p> <p>
The size of the array is part of its type; however, one can declare The size of the array is part of its type; however, one can declare
a <i>slice</i> variable, to which one can assign a pointer to a <i>slice</i> variable to hold a reference to any array, of any size,
any array with the same element type.
with the same element type or&mdash;much more commonly&mdash;a <i>slice A <i>slice
expression</i> of the form <code>a[low : high]</code>, representing expression</i> has the form <code>a[low : high]</code>, representing
the subarray indexed by <code>low</code> through <code>high-1</code>. the internal array indexed from <code>low</code> through <code>high-1</code>; the resulting
Slices look a lot like arrays but have slice is indexed from <code>0</code> through <code>high-low-1</code>.
In short, slices look a lot like arrays but with
no explicit size (<code>[]</code> vs. <code>[10]</code>) and they reference a segment of no explicit size (<code>[]</code> vs. <code>[10]</code>) and they reference a segment of
an underlying, often anonymous, regular array. Multiple slices an underlying, usually anonymous, regular array. Multiple slices
can share data if they represent pieces of the same array; can share data if they represent pieces of the same array;
multiple arrays can never share data. multiple arrays can never share data.
<p> <p>
...@@ -302,12 +303,23 @@ regular arrays; they're more flexible, have reference semantics, ...@@ -302,12 +303,23 @@ regular arrays; they're more flexible, have reference semantics,
and are efficient. What they lack is the precise control of storage and are efficient. What they lack is the precise control of storage
layout of a regular array; if you want to have a hundred elements layout of a regular array; if you want to have a hundred elements
of an array stored within your structure, you should use a regular of an array stored within your structure, you should use a regular
array. array. To create one, use a compound value <i>constructor</i>&mdash;an
expression formed
from a type followed by a brace-bounded expression like this:
<p>
<pre>
[3]int{1,2,3}
</pre>
<p>
In this case the constructor builds an array of 3 <code>ints</code>.
<p> <p>
When passing an array to a function, you almost always want When passing an array to a function, you almost always want
to declare the formal parameter to be a slice. When you call to declare the formal parameter to be a slice. When you call
the function, take the address of the array and Go will the function, slice the array to create
create (efficiently) a slice reference and pass that. (efficiently) a slice reference and pass that.
By default, the lower and upper bounds of a slice match the
ends of the existing object, so the concise notation <code>[:]</code>
will slice the whole array.
<p> <p>
Using slices one can write this function (from <code>sum.go</code>): Using slices one can write this function (from <code>sum.go</code>):
<p> <p>
...@@ -321,32 +333,27 @@ Using slices one can write this function (from <code>sum.go</code>): ...@@ -321,32 +333,27 @@ Using slices one can write this function (from <code>sum.go</code>):
15 } 15 }
</pre> </pre>
<p> <p>
and invoke it like this:
<p>
<pre> <!-- progs/sum.go /1,2,3/ -->
19 s := sum(&amp;[3]int{1,2,3}) // a slice of the array is passed to sum
</pre>
<p>
Note how the return type (<code>int</code>) is defined for <code>sum()</code> by stating it Note how the return type (<code>int</code>) is defined for <code>sum()</code> by stating it
after the parameter list. after the parameter list.
The expression <code>[3]int{1,2,3}</code>&mdash;a type followed by a <p>
brace-bounded To call the function, we slice the array. This intricate call (we'll show
expression&mdash;is a constructor for a value, in this case an array a simpler way in a moment) constructs
of 3 <code>ints</code>. an array and slices it:
Putting an <code>&amp;</code> <p>
in front gives us the address of a unique instance of the value. We pass the <pre>
pointer to <code>sum()</code> by (implicitly) promoting it to a slice. s := sum([3]int{1,2,3}[:])
</pre>
<p> <p>
If you are creating a regular array but want the compiler to count the If you are creating a regular array but want the compiler to count the
elements for you, use <code>...</code> as the array size: elements for you, use <code>...</code> as the array size:
<p> <p>
<pre> <pre>
s := sum(&amp;[...]int{1,2,3}) s := sum([...]int{1,2,3}[:])
</pre> </pre>
<p> <p>
In practice, though, unless you're meticulous about storage layout within a That's fussier than necessary, though.
data structure, a slice itself&mdash;using empty brackets and no In practice, unless you're meticulous about storage layout within a
<code>&amp;</code>&mdash;is all you need: data structure, a slice itself&mdash;using empty brackets with no size&mdash;is all you need:
<p> <p>
<pre> <pre>
s := sum([]int{1,2,3}) s := sum([]int{1,2,3})
...@@ -687,7 +694,7 @@ Building on the <code>file</code> package, here's a simple version of the Unix u ...@@ -687,7 +694,7 @@ Building on the <code>file</code> package, here's a simple version of the Unix u
15 const NBUF = 512 15 const NBUF = 512
16 var buf [NBUF]byte 16 var buf [NBUF]byte
17 for { 17 for {
18 switch nr, er := f.Read(&amp;buf); true { 18 switch nr, er := f.Read(buf[:]); true {
19 case nr &lt; 0: 19 case nr &lt; 0:
20 fmt.Fprintf(os.Stderr, &quot;cat: error reading from %s: %s\n&quot;, f.String(), er.String()) 20 fmt.Fprintf(os.Stderr, &quot;cat: error reading from %s: %s\n&quot;, f.String(), er.String())
21 os.Exit(1) 21 os.Exit(1)
...@@ -803,7 +810,7 @@ and use it from within a mostly unchanged <code>cat()</code> function: ...@@ -803,7 +810,7 @@ and use it from within a mostly unchanged <code>cat()</code> function:
57 r = newRotate13(r) 57 r = newRotate13(r)
58 } 58 }
59 for { 59 for {
60 switch nr, er := r.Read(&amp;buf); { 60 switch nr, er := r.Read(buf[:]); {
61 case nr &lt; 0: 61 case nr &lt; 0:
62 fmt.Fprintf(os.Stderr, &quot;cat: error reading from %s: %s\n&quot;, r.String(), er.String()) 62 fmt.Fprintf(os.Stderr, &quot;cat: error reading from %s: %s\n&quot;, r.String(), er.String())
63 os.Exit(1) 63 os.Exit(1)
......
...@@ -227,14 +227,15 @@ In Go, since arrays are values, it's meaningful (and useful) to talk ...@@ -227,14 +227,15 @@ In Go, since arrays are values, it's meaningful (and useful) to talk
about pointers to arrays. about pointers to arrays.
The size of the array is part of its type; however, one can declare The size of the array is part of its type; however, one can declare
a <i>slice</i> variable, to which one can assign a pointer to a <i>slice</i> variable to hold a reference to any array, of any size,
any array with the same element type.
with the same element type or&mdash;much more commonly&mdash;a <i>slice A <i>slice
expression</i> of the form "a[low : high]", representing expression</i> has the form "a[low : high]", representing
the subarray indexed by "low" through "high-1". the internal array indexed from "low" through "high-1"; the resulting
Slices look a lot like arrays but have slice is indexed from "0" through "high-low-1".
In short, slices look a lot like arrays but with
no explicit size ("[]" vs. "[10]") and they reference a segment of no explicit size ("[]" vs. "[10]") and they reference a segment of
an underlying, often anonymous, regular array. Multiple slices an underlying, usually anonymous, regular array. Multiple slices
can share data if they represent pieces of the same array; can share data if they represent pieces of the same array;
multiple arrays can never share data. multiple arrays can never share data.
...@@ -243,39 +244,43 @@ regular arrays; they're more flexible, have reference semantics, ...@@ -243,39 +244,43 @@ regular arrays; they're more flexible, have reference semantics,
and are efficient. What they lack is the precise control of storage and are efficient. What they lack is the precise control of storage
layout of a regular array; if you want to have a hundred elements layout of a regular array; if you want to have a hundred elements
of an array stored within your structure, you should use a regular of an array stored within your structure, you should use a regular
array. array. To create one, use a compound value <i>constructor</i>&mdash;an
expression formed
from a type followed by a brace-bounded expression like this:
[3]int{1,2,3}
In this case the constructor builds an array of 3 "ints".
When passing an array to a function, you almost always want When passing an array to a function, you almost always want
to declare the formal parameter to be a slice. When you call to declare the formal parameter to be a slice. When you call
the function, take the address of the array and Go will the function, slice the array to create
create (efficiently) a slice reference and pass that. (efficiently) a slice reference and pass that.
By default, the lower and upper bounds of a slice match the
ends of the existing object, so the concise notation "[:]"
will slice the whole array.
Using slices one can write this function (from "sum.go"): Using slices one can write this function (from "sum.go"):
--PROG progs/sum.go /sum/ /^}/ --PROG progs/sum.go /sum/ /^}/
and invoke it like this:
--PROG progs/sum.go /1,2,3/
Note how the return type ("int") is defined for "sum()" by stating it Note how the return type ("int") is defined for "sum()" by stating it
after the parameter list. after the parameter list.
The expression "[3]int{1,2,3}"&mdash;a type followed by a
brace-bounded To call the function, we slice the array. This intricate call (we'll show
expression&mdash;is a constructor for a value, in this case an array a simpler way in a moment) constructs
of 3 "ints". an array and slices it:
Putting an "&amp;"
in front gives us the address of a unique instance of the value. We pass the s := sum([3]int{1,2,3}[:])
pointer to "sum()" by (implicitly) promoting it to a slice.
If you are creating a regular array but want the compiler to count the If you are creating a regular array but want the compiler to count the
elements for you, use "..." as the array size: elements for you, use "..." as the array size:
s := sum(&amp;[...]int{1,2,3}) s := sum([...]int{1,2,3}[:])
In practice, though, unless you're meticulous about storage layout within a That's fussier than necessary, though.
data structure, a slice itself&mdash;using empty brackets and no In practice, unless you're meticulous about storage layout within a
"&amp;"&mdash;is all you need: data structure, a slice itself&mdash;using empty brackets with no size&mdash;is all you need:
s := sum([]int{1,2,3}) s := sum([]int{1,2,3})
......
...@@ -15,7 +15,7 @@ func cat(f *file.File) { ...@@ -15,7 +15,7 @@ func cat(f *file.File) {
const NBUF = 512 const NBUF = 512
var buf [NBUF]byte var buf [NBUF]byte
for { for {
switch nr, er := f.Read(&buf); true { switch nr, er := f.Read(buf[:]); true {
case nr < 0: case nr < 0:
fmt.Fprintf(os.Stderr, "cat: error reading from %s: %s\n", f.String(), er.String()) fmt.Fprintf(os.Stderr, "cat: error reading from %s: %s\n", f.String(), er.String())
os.Exit(1) os.Exit(1)
......
...@@ -15,10 +15,10 @@ var rot13Flag = flag.Bool("rot13", false, "rot13 the input") ...@@ -15,10 +15,10 @@ var rot13Flag = flag.Bool("rot13", false, "rot13 the input")
func rot13(b byte) byte { func rot13(b byte) byte {
if 'a' <= b && b <= 'z' { if 'a' <= b && b <= 'z' {
b = 'a' + ((b - 'a') + 13) % 26 b = 'a' + ((b-'a')+13)%26
} }
if 'A' <= b && b <= 'Z' { if 'A' <= b && b <= 'Z' {
b = 'A' + ((b - 'A') + 13) % 26 b = 'A' + ((b-'A')+13)%26
} }
return b return b
} }
...@@ -57,7 +57,7 @@ func cat(r reader) { ...@@ -57,7 +57,7 @@ func cat(r reader) {
r = newRotate13(r) r = newRotate13(r)
} }
for { for {
switch nr, er := r.Read(&buf); { switch nr, er := r.Read(buf[:]); {
case nr < 0: case nr < 0:
fmt.Fprintf(os.Stderr, "cat: error reading from %s: %s\n", r.String(), er.String()) fmt.Fprintf(os.Stderr, "cat: error reading from %s: %s\n", r.String(), er.String())
os.Exit(1) os.Exit(1)
......
...@@ -16,6 +16,6 @@ func sum(a []int) int { // returns an int ...@@ -16,6 +16,6 @@ func sum(a []int) int { // returns an int
func main() { func main() {
s := sum(&[3]int{1,2,3}) // a slice of the array is passed to sum s := sum([3]int{1, 2, 3}[:]) // a slice of the array is passed to sum
fmt.Print(s, "\n") fmt.Print(s, "\n")
} }
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