mirror of
https://github.com/golang/go
synced 2024-11-25 02:07:58 -07:00
spec changes for panic and recover.
R=rsc, gri CC=golang-dev https://golang.org/cl/763041
This commit is contained in:
parent
6358e1faf6
commit
5bb29fb116
186
doc/go_spec.html
186
doc/go_spec.html
@ -1108,7 +1108,7 @@ The comparison operators <code>==</code> and <code>!=</code>
|
|||||||
key type; thus the key type must be a boolean, numeric, string, pointer, function, interface,
|
key type; thus the key type must be a boolean, numeric, string, pointer, function, interface,
|
||||||
map, or channel type. If the key type is an interface type, these
|
map, or channel type. If the key type is an interface type, these
|
||||||
comparison operators must be defined for the dynamic key values;
|
comparison operators must be defined for the dynamic key values;
|
||||||
failure will cause a run-time error.
|
failure will cause a <a href="#Run_time_panics">run-time panic</a>.
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -2397,7 +2397,8 @@ or for <code>a</code> of type <code>S</code> where <code>S</code> is a <a href="
|
|||||||
<li><code>x</code> must be an integer value and <code>0 <= x < len(a)</code></li>
|
<li><code>x</code> must be an integer value and <code>0 <= x < len(a)</code></li>
|
||||||
<li><code>a[x]</code> is the array element at index <code>x</code> and the type of
|
<li><code>a[x]</code> is the array element at index <code>x</code> and the type of
|
||||||
<code>a[x]</code> is the element type of <code>A</code></li>
|
<code>a[x]</code> is the element type of <code>A</code></li>
|
||||||
<li>if the index <code>x</code> is out of range, a run-time exception occurs</li>
|
<li>if the index <code>x</code> is out of range,
|
||||||
|
a <a href="#Run_time_panics">run-time panic</a> occurs</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -2409,7 +2410,8 @@ where <code>T</code> is a <a href="#String_types">string type</a>:
|
|||||||
<li><code>a[x]</code> is the byte at index <code>x</code> and the type of
|
<li><code>a[x]</code> is the byte at index <code>x</code> and the type of
|
||||||
<code>a[x]</code> is <code>byte</code></li>
|
<code>a[x]</code> is <code>byte</code></li>
|
||||||
<li><code>a[x]</code> may not be assigned to
|
<li><code>a[x]</code> may not be assigned to
|
||||||
<li>if the index <code>x</code> is out of range, a run-time exception occurs</li>
|
<li>if the index <code>x</code> is out of range,
|
||||||
|
a <a href="#Run_time_panics">run-time panic</a> occurs</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -2542,8 +2544,9 @@ of <code>x</code> implements the interface <code>T</code> (§<a href="#Interface
|
|||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
If the type assertion holds, the value of the expression is the value
|
If the type assertion holds, the value of the expression is the value
|
||||||
stored in <code>x</code> and its type is <code>T</code>. If the type assertion is false, a run-time
|
stored in <code>x</code> and its type is <code>T</code>. If the type assertion is false,
|
||||||
exception occurs. In other words, even though the dynamic type of <code>x</code>
|
a <a href="#Run_time_panics">run-time panic</a> occurs.
|
||||||
|
In other words, even though the dynamic type of <code>x</code>
|
||||||
is known only at run-time, the type of <code>x.(T)</code> is
|
is known only at run-time, the type of <code>x.(T)</code> is
|
||||||
known to be <code>T</code> in a correct program.
|
known to be <code>T</code> in a correct program.
|
||||||
</p>
|
</p>
|
||||||
@ -2562,7 +2565,7 @@ the result of the assertion is a pair of values with types <code>(T, bool)</code
|
|||||||
If the assertion holds, the expression returns the pair <code>(x.(T), true)</code>;
|
If the assertion holds, the expression returns the pair <code>(x.(T), true)</code>;
|
||||||
otherwise, the expression returns <code>(Z, false)</code> where <code>Z</code>
|
otherwise, the expression returns <code>(Z, false)</code> where <code>Z</code>
|
||||||
is the <a href="#The_zero_value">zero value</a> for type <code>T</code>.
|
is the <a href="#The_zero_value">zero value</a> for type <code>T</code>.
|
||||||
No run-time exception occurs in this case.
|
No run-time panic occurs in this case.
|
||||||
The type assertion in this construct thus acts like a function call
|
The type assertion in this construct thus acts like a function call
|
||||||
returning a value and a boolean indicating success. (§<a href="#Assignments">Assignments</a>)
|
returning a value and a boolean indicating success. (§<a href="#Assignments">Assignments</a>)
|
||||||
</p>
|
</p>
|
||||||
@ -4281,7 +4284,7 @@ Deferred function calls are executed in LIFO order
|
|||||||
immediately before the surrounding function returns,
|
immediately before the surrounding function returns,
|
||||||
after the return values, if any, have been evaluated, but before they
|
after the return values, if any, have been evaluated, but before they
|
||||||
are returned to the caller. For instance, if the deferred function is
|
are returned to the caller. For instance, if the deferred function is
|
||||||
a <a href="#Function_literals">function literal<a/> and the surrounding
|
a <a href="#Function_literals">function literal</a> and the surrounding
|
||||||
function has <a href="#Function_types">named result parameters</a> that
|
function has <a href="#Function_types">named result parameters</a> that
|
||||||
are in scope within the literal, the deferred function may access and modify
|
are in scope within the literal, the deferred function may access and modify
|
||||||
the result parameters before they are returned.
|
the result parameters before they are returned.
|
||||||
@ -4510,6 +4513,150 @@ var im = imag(b) // has type float
|
|||||||
var rl = real(c64) // type float32
|
var rl = real(c64) // type float32
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
<h3 id="Handling_panics">Handling panics</h3>
|
||||||
|
|
||||||
|
<p> Two built-in functions, <code>panic</code> and <code>recover</code>,
|
||||||
|
assist in reporting and handling <a href="#Run_time_panics">run-time panics</a>
|
||||||
|
and program-defined error conditions.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre class="grammar">
|
||||||
|
func panic(interface{})
|
||||||
|
func recover() interface{}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<font color=red>TODO: Most of this text could move to the respective
|
||||||
|
comments in <code>runtime.go</code> once the functions are implemented.
|
||||||
|
They are here, at least for now, for reference and discussion.
|
||||||
|
</font>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
When a function <code>F</code> calls <code>panic</code>, normal
|
||||||
|
execution of <code>F</code> stops immediately. Any functions whose
|
||||||
|
execution was <a href="#Defer_statements">deferred</a> by the
|
||||||
|
invocation of <code>F</code> are run in the usual way, and then
|
||||||
|
<code>F</code> returns to its caller. To the caller, <code>F</code>
|
||||||
|
then behaves like a call to <code>panic</code>, terminating its own
|
||||||
|
execution and running deferred functions. This continues until all
|
||||||
|
functions in the goroutine have ceased execution, in reverse order.
|
||||||
|
At that point, the program is
|
||||||
|
terminated and the error condition is reported, including the value of
|
||||||
|
the argument to <code>panic</code>. This termination sequence is
|
||||||
|
called <i>panicking</i>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The <code>recover</code> function allows a program to manage behavior
|
||||||
|
of a panicking goroutine. Executing a <code>recover</code> call
|
||||||
|
inside a deferred function (but not any function called by it) stops
|
||||||
|
the panicking sequence by restoring normal execution, and retrieves
|
||||||
|
the error value passed to the call of <code>panic</code>. If
|
||||||
|
<code>recover</code> is called outside the deferred function it will
|
||||||
|
not stop a panicking sequence. In this case, and when the goroutine
|
||||||
|
is not panicking, <code>recover</code> returns <code>nil</code>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If the function defined here,
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
func f(hideErrors bool) {
|
||||||
|
defer func() {
|
||||||
|
if x := recover(); x != nil {
|
||||||
|
println("panicking with value", v)
|
||||||
|
if !hideErrors {
|
||||||
|
panic(x) // go back to panicking
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println("function returns normally") // executes only when hideErrors==true
|
||||||
|
}()
|
||||||
|
println("before")
|
||||||
|
p()
|
||||||
|
println("after") // never executes
|
||||||
|
}
|
||||||
|
|
||||||
|
func p() {
|
||||||
|
panic(3)
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
is called with <code>hideErrors=true</code>, it prints
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
before
|
||||||
|
panicking with value 3
|
||||||
|
function returns normally
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
and resumes normal execution in the function that called <code>f</code>. Otherwise, it prints
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
before
|
||||||
|
panicking with value 3
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
and, absent further <code>recover</code> calls, terminates the program.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Since deferred functions run before assigning the return values to the caller
|
||||||
|
of the deferring function, a deferred invocation of a function literal may modify the
|
||||||
|
invoking function's return values in the event of a panic. This permits a function to protect its
|
||||||
|
caller from panics that occur in functions it calls.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
func IsPrintable(s string) (ok bool) {
|
||||||
|
ok = true
|
||||||
|
defer func() {
|
||||||
|
if recover() != nil {
|
||||||
|
println("input is not printable")
|
||||||
|
ok = false
|
||||||
|
}
|
||||||
|
// Panicking has stopped; execution will resume normally in caller.
|
||||||
|
// The return value will be true normally, false if a panic occurred.
|
||||||
|
}
|
||||||
|
panicIfNotPrintable(s) // will panic if validations fails.
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<!---
|
||||||
|
<p>
|
||||||
|
A deferred function that calls <code>recover</code> will see the
|
||||||
|
argument passed to <code>panic</code>. However, functions called
|
||||||
|
<i>from</i> the deferred function run normally, without behaving as
|
||||||
|
though they are panicking. This allows deferred code to run normally
|
||||||
|
in case recovery is necessary and guarantees that functions that manage
|
||||||
|
their own panics will not fail incorrectly. The function
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
func g() {
|
||||||
|
s := ReadString()
|
||||||
|
defer func() {
|
||||||
|
if IsPrintable(s) {
|
||||||
|
println("finished processing", s)
|
||||||
|
} else {
|
||||||
|
println("finished processing unprintable string")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
Analyze(s)
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
will not cause <code>IsPrintable</code> to print <code>"input is not printable"</code>
|
||||||
|
due to a <code>panic</code> triggered by the call to <code>Analyze</code>.
|
||||||
|
</p>
|
||||||
|
-->
|
||||||
|
|
||||||
<h3 id="Bootstrapping">Bootstrapping</h3>
|
<h3 id="Bootstrapping">Bootstrapping</h3>
|
||||||
|
|
||||||
@ -4524,7 +4671,6 @@ Function Behavior
|
|||||||
|
|
||||||
print prints all arguments; formatting of arguments is implementation-specific
|
print prints all arguments; formatting of arguments is implementation-specific
|
||||||
println like print but prints spaces between arguments and a newline at the end
|
println like print but prints spaces between arguments and a newline at the end
|
||||||
panic like print, aborts execution after printing
|
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
@ -4822,6 +4968,28 @@ Implementation restriction: The compiler assumes package <code>main</code>
|
|||||||
is not imported by any other package.
|
is not imported by any other package.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<h2 id="Run_time_errors">Run-time panics</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Execution errors such as attempting to index an array out
|
||||||
|
of bounds trigger a <i>run-time panic</i> equivalent to a call of
|
||||||
|
the built-in function <a href="#Handling_panics"><code>panic</code></a>
|
||||||
|
with a value of the implementation-defined interface type <code>runtime.Error</code>.
|
||||||
|
That type defines at least the method
|
||||||
|
<code>String() string</code>. The exact error values that
|
||||||
|
represent distinct run-time error conditions are unspecified,
|
||||||
|
at least for now.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
type Error interface {
|
||||||
|
String() string
|
||||||
|
// and perhaps others
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
<h2 id="System_considerations">System considerations</h2>
|
<h2 id="System_considerations">System considerations</h2>
|
||||||
|
|
||||||
<h3 id="Package_unsafe">Package <code>unsafe</code></h3>
|
<h3 id="Package_unsafe">Package <code>unsafe</code></h3>
|
||||||
@ -4942,4 +5110,6 @@ The following minimal alignment properties are guaranteed:
|
|||||||
<li><span class="alert">Gccgo allows only one init() function per source file.</span></li>
|
<li><span class="alert">Gccgo allows only one init() function per source file.</span></li>
|
||||||
<li><span class="alert">Deferred functions cannot access the surrounding function's result parameters.</span></li>
|
<li><span class="alert">Deferred functions cannot access the surrounding function's result parameters.</span></li>
|
||||||
<li><span class="alert">Function results are not addressable.</span></li>
|
<li><span class="alert">Function results are not addressable.</span></li>
|
||||||
|
<li><span class="alert">Recover is not implemented.</span></li>
|
||||||
|
<li><span class="alert">The implemented version of panic differs from its specification.</span></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
Loading…
Reference in New Issue
Block a user