1
0
mirror of https://github.com/golang/go synced 2024-11-24 19:40:09 -07:00

effective_go: redeclaration

Fixes #2455.
Fixes #2013.

R=rsc, r, gri
CC=golang-dev
https://golang.org/cl/5498053
This commit is contained in:
Rob Pike 2011-12-20 14:15:35 -08:00
parent c037d3f254
commit a41006f35a
2 changed files with 100 additions and 0 deletions

View File

@ -531,12 +531,62 @@ if err != nil {
} }
d, err := f.Stat() d, err := f.Stat()
if err != nil { if err != nil {
f.Close()
return err return err
} }
codeUsing(f, d) codeUsing(f, d)
</pre> </pre>
<h3 id="redeclaration">Redeclaration</h3>
<p>
An aside: The last example in the previous section demonstrates a detail of how the
<code>:=</code> short declaration form works.
The declaration that calls <code>os.Open</code> reads,
</p>
<pre>
f, err := os.Open(name)
</pre>
<p>
This statement declares two variables, <code>f</code> and <code>err</code>.
A few lines later, the call to <code>f.Stat</code> reads,
</p>
<pre>
d, err := f.Stat()
</pre>
<p>
which looks as if it declares <code>d</code> and <code>err</code>.
Notice, though, that <code>err</code> appears in both statements.
This duplication is legal: <code>err</code> is declared by the first statement,
but only <em>re-assigned</em> in the second.
This means that the call to <code>f.Stat</code> uses the existing
<code>err</code> variable declared above, and just gives it a new value.
</p>
<p>
In a <code>:=</code> declaration a variable <code>v</code> may appear even
if it has already been declared, provided:
</p>
<ul>
<li>this declaration is in the same scope as the existing declaration of <code>v</code>
(if <code>v</code> is already declared in an outer scope, the declaration will create a new variable),</li>
<li>the corresponding value in the initialization is assignable to <code>v</code>, and</li>
<li>there is at least one other variable in the declaration that is being declared anew.</li>
</ul>
<p>
This unusual property is pure pragmatism,
making it easy to use a single <code>err</code> value, for example,
in a long <code>if-else</code> chain.
You'll see it used often.
</p>
<h3 id="for">For</h3> <h3 id="for">For</h3>
<p> <p>

View File

@ -527,12 +527,62 @@ if err != nil {
} }
d, err := f.Stat() d, err := f.Stat()
if err != nil { if err != nil {
f.Close()
return err return err
} }
codeUsing(f, d) codeUsing(f, d)
</pre> </pre>
<h3 id="redeclaration">Redeclaration</h3>
<p>
An aside: The last example in the previous section demonstrates a detail of how the
<code>:=</code> short declaration form works.
The declaration that calls <code>os.Open</code> reads,
</p>
<pre>
f, err := os.Open(name)
</pre>
<p>
This statement declares two variables, <code>f</code> and <code>err</code>.
A few lines later, the call to <code>f.Stat</code> reads,
</p>
<pre>
d, err := f.Stat()
</pre>
<p>
which looks as if it declares <code>d</code> and <code>err</code>.
Notice, though, that <code>err</code> appears in both statements.
This duplication is legal: <code>err</code> is declared by the first statement,
but only <em>re-assigned</em> in the second.
This means that the call to <code>f.Stat</code> uses the existing
<code>err</code> variable declared above, and just gives it a new value.
</p>
<p>
In a <code>:=</code> declaration a variable <code>v</code> may appear even
if it has already been declared, provided:
</p>
<ul>
<li>this declaration is in the same scope as the existing declaration of <code>v</code>
(if <code>v</code> is already declared in an outer scope, the declaration will create a new variable),</li>
<li>the corresponding value in the initialization is assignable to <code>v</code>, and</li>
<li>there is at least one other variable in the declaration that is being declared anew.</li>
</ul>
<p>
This unusual property is pure pragmatism,
making it easy to use a single <code>err</code> value, for example,
in a long <code>if-else</code> chain.
You'll see it used often.
</p>
<h3 id="for">For</h3> <h3 id="for">For</h3>
<p> <p>