mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-05 20:47:53 +00:00
defer: improve manual, clarify difference wrt try/finally (#16010)
(cherry picked from commit 50d035b789)
This commit is contained in:
@@ -4372,7 +4372,9 @@ Custom exceptions can be raised like any others, e.g.:
|
||||
Defer statement
|
||||
---------------
|
||||
|
||||
Instead of a ``try finally`` statement a ``defer`` statement can be used.
|
||||
Instead of a ``try finally`` statement a ``defer`` statement can be used, which
|
||||
avoids lexical nesting and offers more flexibility in terms of scoping as shown
|
||||
below.
|
||||
|
||||
Any statements following the ``defer`` in the current block will be considered
|
||||
to be in an implicit try block:
|
||||
@@ -4381,7 +4383,7 @@ to be in an implicit try block:
|
||||
:test: "nim c $1"
|
||||
|
||||
proc main =
|
||||
var f = open("numbers.txt")
|
||||
var f = open("numbers.txt", fmWrite)
|
||||
defer: close(f)
|
||||
f.write "abc"
|
||||
f.write "def"
|
||||
@@ -4399,6 +4401,33 @@ Is rewritten to:
|
||||
finally:
|
||||
close(f)
|
||||
|
||||
When `defer` is at the outermost scope of a template/macro, its scope extends
|
||||
to the block where the template is called from:
|
||||
|
||||
.. code-block:: nim
|
||||
:test: "nim c $1"
|
||||
|
||||
template safeOpenDefer(f, path) =
|
||||
var f = open(path, fmWrite)
|
||||
defer: close(f)
|
||||
|
||||
template safeOpenFinally(f, path, body) =
|
||||
var f = open(path, fmWrite)
|
||||
try: body # without `defer`, `body` must be specified as parameter
|
||||
finally: close(f)
|
||||
|
||||
block:
|
||||
safeOpenDefer(f, "/tmp/z01.txt")
|
||||
f.write "abc"
|
||||
block:
|
||||
safeOpenFinally(f, "/tmp/z01.txt"):
|
||||
f.write "abc" # adds a lexical scope
|
||||
block:
|
||||
var f = open("/tmp/z01.txt", fmWrite)
|
||||
try:
|
||||
f.write "abc" # adds a lexical scope
|
||||
finally: close(f)
|
||||
|
||||
Top-level ``defer`` statements are not supported
|
||||
since it's unclear what such a statement should refer to.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user