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:
parent
c037d3f254
commit
a41006f35a
@ -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>
|
||||||
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user