defer
Go ์ธ์ด์ defer ๋ฌธ๋ฒ๊ณผ ํ์ฉ
Section titled โGo ์ธ์ด์ defer ๋ฌธ๋ฒ๊ณผ ํ์ฉโGo ์ธ์ด๋ ๋ฆฌ์์ค ์ ๋ฆฌ์ ์์ธ ์ฒ๋ฆฌ์ ๋จ์ํ์ ํฐ ๊ฐ์น๋ฅผ ๋๋ฉฐ, ์ด๋ฅผ ๋ํํ๋ ๋ฌธ๋ฒ์ด defer์ด๋ค. defer๋ ํจ์ ์คํ์ด ๋๋๊ธฐ ์ง์ ์์ฝ๋ ๋์์ ์ํํ๋ค. ์ด ๋ฌธ๋ฒ์ Python์ with ๊ตฌ๋ฌธ์ด๋ Java, C++์ try/finally ๊ตฌ๋ฌธ๊ณผ ์ ์ฌํ ์ญํ ์ ํ๋ฉด์๋ Go๋ค์ด ๊ฐ๊ฒฐํจ์ ์ ์งํ๋ค.
defer์ ๋์ ์๋ฆฌ
Section titled โdefer์ ๋์ ์๋ฆฌโdefer๋ ํธ์ถ๋ ์์๋๋ก ์คํ์ ์์ด๊ณ , ํจ์๊ฐ ์ข ๋ฃ๋ ๋ ์ญ์์ผ๋ก ์คํ๋๋ค. ๋ค์ ์์ ๋ ์ด ์๋ฆฌ๋ฅผ ์ง๊ด์ ์ผ๋ก ๋ณด์ฌ์ค๋ค.
package main
import "fmt"
func main() { fmt.Println("start")
defer fmt.Println("first defer") defer fmt.Println("second defer") defer fmt.Println("third defer")
fmt.Println("end")}์คํ ๊ฒฐ๊ณผ๋ ๋ค์๊ณผ ๊ฐ๋ค.
startendthird defersecond deferfirst defer๋ฆฌ์์ค ์ ๋ฆฌ์์์ ํ์ฉ
Section titled โ๋ฆฌ์์ค ์ ๋ฆฌ์์์ ํ์ฉโ๋ฆฌ์์ค ํด์ ๋ ํจ์ ๋ณธ๋ฌธ์์ ์ฌ๋ฌ ์ง์ ์ return์ด ๋ฑ์ฅํ ๋ ํนํ ์ทจ์ฝํ๋ค. defer๋ฅผ ํ์ฉํ๋ฉด ๋ฆฌ์์ค๋ฅผ ํ๋ํ ์์ ์์ ์ ๋ฆฌ ์ ์ฐจ๋ฅผ ์์ฝํ ์ ์์ด ์ฝ๋์ ์ ๋ขฐ์ฑ์ ๋์ธ๋ค.
func readFile(name string) ([]byte, error) { f, err := os.Open(name) if err != nil { return nil, err } defer f.Close()
return io.ReadAll(f)}๋ฝ ํด์ ์์๋ ๋์ผํ ํจํด์ด ์ฐ์ธ๋ค.
func updateSharedData(mu *sync.Mutex, data *int) { mu.Lock() defer mu.Unlock()
*data++}์ต๋ช
ํจ์์ defer
Section titled โ์ต๋ช
ํจ์์ deferโdefer๋ ๋จ์ผ ํธ์ถ๋ฟ ์๋๋ผ ์ฌ๋ฌ ์ค์ ์ ๋ฆฌ ๋ก์ง๋ ์์ฝํ ์ ์๋ค. ์ด๋ ์ต๋ช ํจ์๋ฅผ ํ์ฉํ๋ค.
defer func() { fmt.Println("cleanup start") recover() fmt.Println("cleanup done")}()์ด ๋ฐฉ์์ ๋ก์ปฌ ๋ณ์๋ฅผ ์บก์ฒํ๊ฑฐ๋ panic์ ๋ณต๊ตฌํ๋ ๋ฐ ์ ์ฉํ๋ค.
๋ฃจํ ๋ณ์์ ์บก์ฒ
Section titled โ๋ฃจํ ๋ณ์์ ์บก์ฒโ๋ฃจํ์์ defer๋ฅผ ์ฌ์ฉํ ๋๋ ๋ณ์ ์บก์ฒ ๋ฐฉ์์ ์ฃผ์ํด์ผ ํ๋ค. ์ต๋ช ํจ์๊ฐ ๋ณ์๋ฅผ ์ง์ ์บก์ฒํ๋ฉด ๋ฐ๋ณต๋ฌธ ์ข ๋ฃ ์์ ์ ์ต์ข ๊ฐ์ด ๋ฐ์๋๋ค.
for i := 0; i < 3; i++ { defer func() { fmt.Println("wrong:", i) }()}์ ์ฝ๋๋ 3์ ์ธ ๋ฒ ์ถ๋ ฅํ๋ค. ์๋ํ ๊ฐ์ ์ถ๋ ฅํ๋ ค๋ฉด ์ธ์ ์ ๋ฌ์ ํตํด ๊ฐ์ ๋ณต์ฌํด์ผ ํ๋ค.
Go 1.22+: Go 1.22๋ถํฐ ๋ฃจํ ๋ณ์์ ์ค์ฝํ์ด ๋ณ๊ฒฝ๋์ด, ๊ฐ ๋ฐ๋ณต(iteration)๋ง๋ค ๋ณ์์ ์ ์ธ์คํด์ค๊ฐ ์์ฑ๋๋ค. ๋ฐ๋ผ์ Go 1.22 ์ด์์์๋ ์์ โ์๋ชป๋โ ์์ ๋ ์ฌ๋ฐ๋ฅด๊ฒ 2, 1, 0์ ์ถ๋ ฅํ๋ค. ๊ทธ๋ฌ๋ ์ด์ ๋ฒ์ ๊ณผ์ ํธํ์ฑ์ ์ํด ์ธ์ ์ ๋ฌ ๋ฐฉ์์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ฌ์ ํ ๊ถ์ฅ๋๋ค.
for i := 0; i < 3; i++ { defer func(val int) { fmt.Println("correct:", val) }(i)}panic๊ณผ defer
Section titled โpanic๊ณผ deferโํจ์ ์คํ ์ค panic์ด ๋ฐ์ํด๋ defer๋ ๋ณด์ฅ๋๋ค. ๋ฐ๋ผ์ cleanup ๋ก์ง์ ํญ์ ์คํ๋๋ค.
func main() { defer fmt.Println("cleanup 1") defer fmt.Println("cleanup 2")
fmt.Println("before panic") panic("something went wrong")}์ถ๋ ฅ์ ๋ค์๊ณผ ๊ฐ๋ค.
before paniccleanup 2cleanup 1panic: something went wrong๋ฐํ๊ฐ ์์
Section titled โ๋ฐํ๊ฐ ์์ โdefer๋ named return ๊ฐ์ ์์ ํ๋ ๋ฐ๋ ์ฐ์ผ ์ ์๋ค.
func f() (n int) { defer func() { n += 10 }() n = 5 return}
func main() { fmt.Println(f()) // 15}์ด ๊ธฐ๋ฅ์ ์ ์คํ๊ฒ ์ฌ์ฉํ ํ์๊ฐ ์๋ค. ์๋๊ฐ ๋ช ํํ์ง ์์ผ๋ฉด ๊ฐ๋ ์ฑ์ ํด์น ์ ์๋ค.
defer๋ ๋ฆฌ์์ค ์ ๋ฆฌ์ ์์ธ ์์ ์ฑ์ ๋จ์ํ ๊ตฌ๋ฌธ์ผ๋ก ํด๊ฒฐํ๋ Go ์ธ์ด์ ์ค์ํ ์ฅ์น์ด๋ค. ๋ฆฌ์์ค๋ฅผ ํ๋ํ ์ฆ์ ์ ๋ฆฌ๋ฅผ ์์ฝํ๋ ์ต๊ด์ ์์ ํ ์ฝ๋ ์์ฑ์ ๋๋๋ค. defer๋ ์คํ ๊ธฐ๋ฐ ์คํ, ์ต๋ช ํจ์ ํ์ฉ, panic ๋ณต๊ตฌ ์ง์ ๋ฑ์ ํตํด Python์ ์ปจํ ์คํธ ๋งค๋์ ์ ๊ฐ์ ์ญํ ์ ์ํํ๋ฉด์๋ Go์ ๊ฐ๊ฒฐํ ์ฒ ํ์ ์ ๋ณด์ฌ์ค๋ค.