mirror of
https://github.com/golang/go
synced 2024-11-22 02:04:40 -07:00
Effective Go: append and a few words about ...
R=rsc, gri, iant CC=golang-dev https://golang.org/cl/2821041
This commit is contained in:
parent
c33289238e
commit
0808b199e0
@ -1218,6 +1218,11 @@ func Append(slice, data[]byte) []byte {
|
|||||||
We must return the slice afterwards because, although <code>Append</code>
|
We must return the slice afterwards because, although <code>Append</code>
|
||||||
can modify the elements of <code>slice</code>, the slice itself (the run-time data
|
can modify the elements of <code>slice</code>, the slice itself (the run-time data
|
||||||
structure holding the pointer, length, and capacity) is passed by value.
|
structure holding the pointer, length, and capacity) is passed by value.
|
||||||
|
<p>
|
||||||
|
The idea of appending to a slice is so useful it's captured by the
|
||||||
|
<code>append</code> built-in function. To understand that function's
|
||||||
|
design, though, we need a little more information, so we'll return
|
||||||
|
to it later.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
@ -1465,6 +1470,10 @@ func Println(v ...interface{}) {
|
|||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
|
We write <code>...</code> after <code>v</code> in the call to <code>Output</code> to tell the
|
||||||
|
compiler to treat <code>v</code> as a list of arguments; otherwise it would just pass
|
||||||
|
<code>v</code> as a single slice argument.
|
||||||
|
<p>
|
||||||
There's even more to printing than we've covered here. See the <code>godoc</code> documentation
|
There's even more to printing than we've covered here. See the <code>godoc</code> documentation
|
||||||
for package <code>fmt</code> for the details.
|
for package <code>fmt</code> for the details.
|
||||||
</p>
|
</p>
|
||||||
@ -1484,6 +1493,47 @@ func Min(a ...int) int {
|
|||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
<h3 id="append">Append</h3>
|
||||||
|
<p>
|
||||||
|
Now we have the missing piece we needed to explain the design of
|
||||||
|
the <code>append</code> built-in function. The signature of <code>append</code>
|
||||||
|
is different from our custom <code>Append</code> function above.
|
||||||
|
Schematically, it's like this:
|
||||||
|
<pre>
|
||||||
|
func append(slice []<i>T</i>, elements...T) []<i>T</i>
|
||||||
|
</pre>
|
||||||
|
where <i>T</i> is a placeholder for any given type. You can't
|
||||||
|
actually write a function in Go where the type <code>T</code>
|
||||||
|
is determined by the caller.
|
||||||
|
That's why <code>append</code> is built in: it needs support from the
|
||||||
|
compiler.
|
||||||
|
<p>
|
||||||
|
What <code>append</code> does is append the elements to the end of
|
||||||
|
the slice and return the result. The result needs to be returned
|
||||||
|
because, as with our hand-written <code>Append</code>, the underlying
|
||||||
|
array may change. This simple example
|
||||||
|
<pre>
|
||||||
|
x := []int{1,2,3}
|
||||||
|
x = append(x, 4, 5, 6)
|
||||||
|
fmt.Println(x)
|
||||||
|
</pre>
|
||||||
|
prints <code>[1 2 3 4 5 6]</code>. So <code>append</code> works a
|
||||||
|
little like <code>Printf</code>, collecting an arbitrary number of
|
||||||
|
arguments.
|
||||||
|
<p>
|
||||||
|
But what if we wanted to do what our <code>Append</code> does and
|
||||||
|
append a slice to a slice? Easy: use <code>...</code> at the call
|
||||||
|
site, just as we did in the call to <code>Output</code> above. This
|
||||||
|
snippet produces identical output to the one above.
|
||||||
|
<pre>
|
||||||
|
x := []int{1,2,3}
|
||||||
|
y := []int{4,5,6}
|
||||||
|
x = append(x, y...)
|
||||||
|
fmt.Println(x)
|
||||||
|
</pre>
|
||||||
|
Without that <code>...</code>, it wouldn't compile because the types
|
||||||
|
would be wrong; <code>y</code> is not of type <code>int</code>.
|
||||||
|
|
||||||
<h2 id="initialization">Initialization</h2>
|
<h2 id="initialization">Initialization</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
Loading…
Reference in New Issue
Block a user