defer, stejně jako třeba if může za sebou mít buď jeden příkaz nebo celý { blok; příkazů; }
K celému spuštění dojde až na konci scopu v kterém byl defer zaregistrován.
nic se nepředvyhodnocuje, lze si to představit jakoby defer vložil jeho kód do všech míst kde může končit scope.
Defer má stále přístup k lokálním proměnným, takže není žádný problém vyhodnotit vše na konci scopu.
Defer má stále přístup k lokálním proměnným, takže není žádný problém vyhodnotit vše na konci scopu.
Problém by to byl, když se hodnota té proměnné změní: volám-li defer třeba z cyklu, kde otevírám soubory a jejich deskriptor ukládám do stejné proměnné. Pro jsem se naivně ptal - trochu mne k tomu navedla zmínka, že defer používá zásobník...
Ale stačí vědět, že takhle se defer použít nedá a je to jednodušší, než přemýšlet, která část příkazu se vyhodnotí hned a která se odloží.
Tak běžně při první chybě lezu z funkce (nebo scopu) ven a tímpádem se hned zavolá defer kód, čili ke změně proměnných nedochází.
if(chyba)
return; // tady se mi zavolá defer kód
Účelem deferu je umožnit po sobě elegantně uklidit, bez duplikovaného kódu, bez možnosti vynechat (opomenout) nějaký třeba nově přidaný return.
Ještě jednodušší než přemýšlet která část příkazu se vyhodnotí hned a která se odloží je uvědomit si, že žádná se nevyhodnotí hned a vše se odloží - pak není nad čím přemýšlet :-)
Pokud bych však přesto všechno z nějakého důvodu potřeboval například vypsat hodnotu o které vím že před exitem scopu se ta hodnota změní, tak to taky není žádný problém. Mohu si při chybě alokovat paměť, do ní zapsat aktualní hodnotu nebo rovnou zformátovanou log message a v defer části ji vypsat a a uvolnit alokovanou paměť.
14. 10. 2025, 15:43 editováno autorem komentáře