@@ -2301,25 +2301,27 @@ The above code prints:
23012301
23022302### Defer
23032303
2304- A defer statement defers the execution of a block of statements
2305- until the surrounding function returns.
2304+ A ` defer {} ` statement, defers the execution of the block of statements
2305+ until the surrounding scope of the defer ends. It is a convenient feature
2306+ that allows you to group related actions (getting access to a resource
2307+ and cleaning/freeing it after you are done) closely together, instead
2308+ of spreading them across multiple potentially very remote lines of code.
23062309
23072310``` v
23082311import os
23092312
2310- fn read_log() {
2313+ fn read_log() ! {
23112314 mut ok := false
2312- mut f := os.open('log.txt') or { panic(err) }
2313- defer {
2314- f.close()
2315- }
2315+ mut f := os.open('log.txt')!
2316+ defer { f.close() }
23162317 // ...
23172318 if !ok {
2319+ // ...
23182320 // defer statement will be called here, the file will be closed
23192321 return
23202322 }
23212323 // ...
2322- // defer statement will be called here, the file will be closed
2324+ // defer statement will be called here too , the file will be closed
23232325}
23242326```
23252327
@@ -2402,6 +2404,52 @@ fn (mut app App) auth_with_user_middleware() (bool, string) {
24022404}
24032405```
24042406
2407+ #### defer in loop scopes:
2408+ Defer can be used inside loops too, and the deferred statement will be executed once for each
2409+ iteration. You can also have multiple defer statements in the same scope, in which case, they
2410+ will be executed in reverse order of their appearance in the source code:
2411+ ``` v
2412+ fn main() {
2413+ defer { println('Program finish.') }
2414+ println('Loop start.')
2415+ for i in 1 .. 4 {
2416+ defer { println('Deferred execution for ${i}. Defer 1.') }
2417+ defer { println('Deferred execution for ${i}. Defer 2.') }
2418+ defer { println('Deferred execution for ${i}. Defer 3.') }
2419+ println('Loop iteration: ${i}')
2420+ }
2421+ println('Loop done.')
2422+ }
2423+ ```
2424+
2425+ The example will print this:
2426+ ``` txt
2427+ Loop start.
2428+ Loop iteration: 1
2429+ Deferred execution for 1. Defer 3.
2430+ Deferred execution for 1. Defer 2.
2431+ Deferred execution for 1. Defer 1.
2432+ Loop iteration: 2
2433+ Deferred execution for 2. Defer 3.
2434+ Deferred execution for 2. Defer 2.
2435+ Deferred execution for 2. Defer 1.
2436+ Loop iteration: 3
2437+ Deferred execution for 3. Defer 3.
2438+ Deferred execution for 3. Defer 2.
2439+ Deferred execution for 3. Defer 1.
2440+ Loop done.
2441+ Program finish.
2442+ ```
2443+
2444+ #### defer(fn) {}
2445+
2446+ Note, that in most of the examples above, the ` defer{} ` statement was directly inside
2447+ a function scope, so it was executed when the function itself returned. Sometimes, you
2448+ need to defer a statement to execute right at the function end (like the above), even
2449+ if you are inside an inner scope (deep inside an ` if ` or ` for ` ).
2450+
2451+ For these more rare cases, you can use: ` defer(fn) {} ` instead of just ` defer {} ` .
2452+
24052453### Goto
24062454
24072455V allows unconditionally jumping to a label with ` goto ` . The label name must be contained
0 commit comments