mirror of
https://github.com/golang/go
synced 2024-11-05 18:36:08 +00: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
1 changed files with 178 additions and 8 deletions
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,
|
||||
map, or channel type. If the key type is an interface type, these
|
||||
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>
|
||||
|
||||
|
@ -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>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>
|
||||
<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>
|
||||
|
||||
<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
|
||||
<code>a[x]</code> is <code>byte</code></li>
|
||||
<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>
|
||||
|
||||
<p>
|
||||
|
@ -2542,8 +2544,9 @@ of <code>x</code> implements the interface <code>T</code> (§<a href="#Interface
|
|||
</p>
|
||||
<p>
|
||||
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
|
||||
exception occurs. In other words, even though the dynamic type of <code>x</code>
|
||||
stored in <code>x</code> and its type is <code>T</code>. If the type assertion is false,
|
||||
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
|
||||
known to be <code>T</code> in a correct program.
|
||||
</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>;
|
||||
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>.
|
||||
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
|
||||
returning a value and a boolean indicating success. (§<a href="#Assignments">Assignments</a>)
|
||||
</p>
|
||||
|
@ -4281,7 +4284,7 @@ Deferred function calls are executed in LIFO order
|
|||
immediately before the surrounding function returns,
|
||||
after the return values, if any, have been evaluated, but before they
|
||||
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
|
||||
are in scope within the literal, the deferred function may access and modify
|
||||
the result parameters before they are returned.
|
||||
|
@ -4510,6 +4513,150 @@ var im = imag(b) // has type float
|
|||
var rl = real(c64) // type float32
|
||||
</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>
|
||||
|
||||
|
@ -4524,7 +4671,6 @@ Function Behavior
|
|||
|
||||
print prints all arguments; formatting of arguments is implementation-specific
|
||||
println like print but prints spaces between arguments and a newline at the end
|
||||
panic like print, aborts execution after printing
|
||||
</pre>
|
||||
|
||||
|
||||
|
@ -4822,6 +4968,28 @@ Implementation restriction: The compiler assumes package <code>main</code>
|
|||
is not imported by any other package.
|
||||
</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>
|
||||
|
||||
<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">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">Recover is not implemented.</span></li>
|
||||
<li><span class="alert">The implemented version of panic differs from its specification.</span></li>
|
||||
</ul>
|
||||
|
|
Loading…
Reference in a new issue