Alert
์ด ๊ธ์ Claude Code์ ๋์์ ๋ฐ์ ์์ฑ๋์์ต๋๋ค
TL;DR
- Go์๋ try/except ๊ฐ์ ์์ธ ๊ตฌ๋ฌธ์ด ์๊ณ , ํจ์๊ฐ ์๋ฌ๋ฅผ ๊ฐ์ผ๋ก ๋ฐํํด ํธ์ถ์๊ฐ
if err != nil๋ก ํ์ธํ๋ ๋ฐฉ์error๋Error() stringํ๋๋ง ๊ฐ์ง ์ธํฐํ์ด์ค์ด๊ณ , nil์ด ์ธํฐํ์ด์ค์ zero value๋ผ โ์๋ฌ ์์ = nilโ์ด ์ฑ๋ฆฝ- ์๋ฌ ์์ฑ์
errors.New์ ํฌ๋งคํ ์ฉfmt.Errorf, ๋ฐํ์(๊ฒฐ๊ณผ, error)๋ค์ค ๋ฐํ ๊ด์ฉ๊ตฌ- ์ผํฐ๋ฌ ์ค๋ฅ๋ ๋ฏธ๋ฆฌ ์ ์ํ ๋ํ ์๋ฌ ๊ฐ์ด๋ฉฐ, ๋ฌธ์์ด ๋น๊ต ๋์
errors.Is๋ก ์ข ๋ฅ๋ฅผ ๊ตฌ๋ถ%w๋ก ๋ฌธ๋งฅ์ ๋ง๋ถ์ฌ ๋ํํ๋ฉด ์๋ณธ์ด ๋ณด์กด๋๊ณ ,errors.Is(๊ฐ ๋น๊ต)ยทerrors.As(ํ์ ํ์ธ ํ ์ถ์ถ)๋ก ์ฒด์ธ์ ๊ฒ์ฌ- panic/recover๋ ํธ์ถ์๊ฐ ์ ์ ์ฒ๋ฆฌํ ์ ์๋ ์น๋ช ์ ์ํฉ ์ ์ฉ์ด๋ฉฐ, ์ผ์ ํ๋ฆ ์ ์ด์ฉ์ด ์๋
Python์์ ์๋ฌ๋ ์์ธ(exception)๋ค. ํจ์ ์ด๋์๋ raise๋ก ๋์ง๊ณ , ํธ์ถ ํ๋ฆ ์ด๋๊ฐ์ try/except๊ฐ ๋ฐ๋๋ค. ๋ฐ์ง ๋ชปํ๋ฉด ํ๋ก๊ทธ๋จ์ด ์ฃฝ๋๋ค. ๋์ง๋ ์ชฝ๊ณผ ๋ฐ๋ ์ชฝ์ด ์ฝ๋์ ๋จ์ด์ ธ ์์ด๋ ๋์ํ๋ ๊ฒ ์์ธ์ ์ฅ์ ์ด์, ํ๋ฆ์ด ์ด๋๋ก ํ๋์ง ์๊ธฐ ์ด๋ ค์ด ๋จ์ ์ด๋ค.
Go๋ ์ ๋ฐ๋๋ก ์ค๊ณ๋๋ค. ์๋ฌ๋ฅผ ๋์ง๋ ํน๋ณํ ๊ตฌ๋ฌธ์ด ์๋ค. ํจ์๋ ์๋ฌ๋ฅผ ๊ฐ์ผ๋ก ๋ฐํํ๊ณ , ํธ์ถ์๋ ๊ทธ ๊ฐ์ ๋งค๋ฒ ์์ผ๋ก ํ์ธํ๋ค. โerrors are valuesโ(์๋ฌ๋ ๊ฐ์ด๋ค)๋ผ๋ ํ ์ค์ด Go ์๋ฌ ์ฒ๋ฆฌ ์ฒ ํ์ ์ ๋ถ๋ค. ๋์ง๊ณ ๋ฐ๋ ๋ง๋ฒ ๋์ , ๋ฐํ๊ฐ์ผ๋ก ์ฃผ๊ณ ๋ฐ๋ ํ๋ฒํ ๋ฐ์ดํฐ๋ก ๋ค๋ฃฌ๋ค. ์ด ๊ธ์ Python์ ์์ธ์ ์ต์ํ ๊ฐ๋ฐ์๊ฐ Go์ ์ด ๋ฐฉ์์ ์ฒ์ ๋ง๋ฌ์ ๋ ํท๊ฐ๋ฆฌ๋ ์ง์ ์ ์ ๋ฆฌํ๋ค.
1. error๋ ์ธํฐํ์ด์ค๋ค
Go์์ error๋ ํน๋ณํ ํค์๋๊ฐ ์๋๋ผ ๋ด์ฅ ์ธํฐํ์ด์ค๋ค. ์ ์๋ ์ด๊ฒ ์ ๋ถ๋ค.
type error interface {
Error() string
}Error() string ๋ฉ์๋ ํ๋๋ง ๊ตฌํํ๋ฉด ์ด๋ค ํ์
์ด๋ ์๋ฌ๊ฐ ๋๋ค. 07ํธ์์ ๋ค๋ฃฌ ๋๋ก Go ์ธํฐํ์ด์ค๋ ๋ฉ์๋ ์งํฉ๋ง ๋ง์กฑํ๋ฉด ์๋์ผ๋ก ์ถฉ์กฑ๋๋ฏ๋ก, ๋ณ๋ ์์์ด๋ ๋ฑ๋ก ์์ด๋ ๋ด ํ์
์ ์๋ฌ๋ก ์ธ ์ ์๋ค.
type MyError struct {
Code int
}
func (e MyError) Error() string {
return fmt.Sprintf("error code %d", e.Code)
}์ด์ MyError๋ error ์ธํฐํ์ด์ค๋ฅผ ๋ง์กฑํ๋ค. ํจ์๊ฐ error๋ฅผ ๋ฐํํ๋ ์๋ฆฌ์ MyError๋ฅผ ๊ทธ๋๋ก ๋๋ ค์ค ์ ์๋ค.
nil์ด โ์๋ฌ ์์โ์ธ ์ด์
์ฌ๊ธฐ์ ์ธํฐํ์ด์ค์ ์ฑ์ง ํ๋๊ฐ ํต์ฌ์ผ๋ก ์๋ํ๋ค. nil์ ๋ชจ๋ ์ธํฐํ์ด์ค ํ์
์ zero value๋ค(06ํธ์์ ํฌ์ธํฐ์ zero value๊ฐ nil์ด์๋ ๊ฒ๊ณผ ๊ฐ์ ๋งฅ๋ฝ์ด๋ค). error๋ ์ธํฐํ์ด์ค์ด๋ฏ๋ก, ์์ง ์๋ฌด ์๋ฌ๋ ๋ด๊ธฐ์ง ์์ ์ํ๋ ์์ฐ์ค๋ฝ๊ฒ nil์ด ๋๋ค.
๊ทธ๋์ Go๋ โ์๋ฌ๊ฐ ์๋คโ๋ฅผ ํํํ๋ ๋ฐ ๋ณ๋ ์ฅ์น๊ฐ ํ์ ์๋ค. ๊ทธ๋ฅ nil์ ๋ฐํํ๋ฉด ๋๋ค. ํธ์ถ์๋ err == nil์ด๋ฉด ์ฑ๊ณต, err != nil์ด๋ฉด ์คํจ๋ก ์ฝ๋๋ค. ์ด ๋จ์ํ ๊ท์น์ด ๋ค์ ๋์ฌ ๋ชจ๋ ํจํด์ ํ ๋๋ค.
Python์ None๊ณผ ๋ค๋ฅธ ์
Python์์
None์ โ๊ฐ์ด ์์โ์ ๋ปํ๋ ๋จ์ผ ๊ฐ์ฒด์ผ ๋ฟ, ์๋ฌ ์ฒ๋ฆฌ์ ์ง์ ์ฐ๊ฒฐ๋์ง ์๋๋ค. ์๋ฌ๋ ์์ธ๋ก ๋ฐ๋ก ๋์ง๋ค. Go์ nil์ โ์๋ฌ ์์โ์ด๋ผ๋ ์๋ฏธ๋ฅผ ์๋ฌ ์ฒ๋ฆฌ ๊ท์ฝ ์์ฒด์ ๋ น์ฌ ์ด๋ค. ํจ์๊ฐerror๋ฅผ ๋ฐํํ๋๋ฐ nil์ด๋ฉด, ๊ทธ๊ฑด ๊ณง โ์ด๋ฒ์ ๋ฌธ์ ์๋คโ๋ ๋ป์ด๋ค.
2. ์๋ฌ ๋ง๋ค๊ณ ๋ฐํํ๊ธฐ
์๋ฌ ๊ฐ์ ๋ง๋๋ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ๋ฐฉ๋ฒ์ ๋ ๊ฐ์ง๋ค.
errors.New("๋ฉ์์ง")โ ๊ณ ์ ๋ฌธ์์ด ์๋ฌ๋ฅผ ๋ง๋ ๋คfmt.Errorf("ํ์ %v", ๊ฐ)โ ๊ฐ์ ๋ผ์ ๋ฃ์ด ํฌ๋งคํ ํ ์๋ฌ๋ฅผ ๋ง๋ ๋ค
import (
"errors"
"fmt"
)
func sqrt(x float64) (float64, error) {
if x < 0 {
return 0, errors.New("์์์ ์ ๊ณฑ๊ทผ์ ์ ์๋์ง ์์")
}
if x > 1e308 {
return 0, fmt.Errorf("์
๋ ฅ๊ฐ์ด ๋๋ฌด ํผ: %v", x)
}
return math.Sqrt(x), nil
}
errors.New๋ ์ด๋ป๊ฒ ๋์ํ๋
errors.New(text)๋ ๋ด๋ถ์ ์ผ๋กtext๋ฅผ ์์ ๊ตฌ์กฐ์ฒด์ ๋ด๊ณ ๊ทธ ํฌ์ธํฐ๋ฅผ ๋ฐํํ๋ค. ๊ทธ ๊ตฌ์กฐ์ฒด๊ฐError() string๋ฉ์๋ ํ๋๋ฅผ ๊ฐ์ ธerror์ธํฐํ์ด์ค๋ฅผ ๋ง์กฑํ๋ฏ๋ก(07ํธ),err.Error()๋fmt.Println(err)์ ๊ทธ ๋ฉ์๋๋ฅผ ๋ถ๋ฌ ๋ด์๋ ํ ์คํธ๋ฅผ ๊บผ๋ธ๋ค.// ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ (์์ฝ) func New(text string) error { return &errorString{text} } type errorString struct{ s string } func (e *errorString) Error() string { return e.s }ํฌ์ธํฐ๋ฅผ ๋ฐํํ๋ฏ๋ก ํ ์คํธ๊ฐ ๊ฐ์๋ ํธ์ถ๋ง๋ค ๋ค๋ฅธ ๊ฐ์ด ๋๋ค(
errors.New("x") == errors.New("x")๋ false). ์ด โ๊ฐ๋ง๋ค ๊ณ ์ ํจโ์ด 3๋ฒ ์ผํฐ๋ฌ ์ค๋ฅ์์errors.Is๊ฐ ์ ํํ ๊ทธ ๊ฐ๋ง ์ก์๋ด๋ ํ ๋๊ฐ ๋๋ค.
(๊ฒฐ๊ณผ, error) ๋ค์ค ๋ฐํ ๊ด์ฉ๊ตฌ
05ํธ์์ ์๊ณ ํ ํจํด์ด ์ฌ๊ธฐ์ ๋ณธ๊ฒฉ์ ์ผ๋ก ๋ฑ์ฅํ๋ค. Go ํจ์๋ ์ฌ๋ฌ ๊ฐ์ ๋ฐํํ ์ ์๊ณ , ๊ทธ์ค ๋ง์ง๋ง ๋ฐํ๊ฐ์ error ํ์
์ผ๋ก ๋๋ ๊ฒ์ด ๊ด์ฉ๊ตฌ๋ค.
func divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("0์ผ๋ก ๋๋ ์ ์์")
}
return a / b, nil
}์ฑ๊ณตํ๋ฉด (๊ฒฐ๊ณผ, nil), ์คํจํ๋ฉด (zero value, ์๋ฌ)๋ฅผ ๋ฐํํ๋ค. ์คํจ ์ ์ฒซ ๋ฐํ๊ฐ์ 0์ด๋ ๋น ๊ฐ์ผ๋ก ์ฑ์ฐ๋ ๊ฑด ๊ด๋ก๋ค. ์ด์ฐจํผ ํธ์ถ์๊ฐ ์๋ฌ๋ฅผ ๋จผ์ ํ์ธํ๊ณ ๊ฒฐ๊ณผ๋ ์ ์ธ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
ํธ์ถํ๋ ์ชฝ์ ๋ฐํ๋ ์๋ฌ๋ฅผ ๊ณง๋ฐ๋ก ํ์ธํ๋ค.
result, err := divide(10, 0)
if err != nil {
fmt.Println("์คํจ:", err)
return
}
fmt.Println("๊ฒฐ๊ณผ:", result)if err != nil๋ก ์์ํ๋ ์ด ๋ธ๋ก์ด Go ์ฝ๋ ์ ๋ฐ์ ๋์์ด ๋ฐ๋ณต๋๋ค. ์ฒ์์ ์ฅํฉํด ๋ณด์ด์ง๋ง, ์๋ฌ๊ฐ ๋ฐ์ํ ์ ์๋ ๋ชจ๋ ์ง์ ์ด ์ฝ๋์ ๊ทธ๋๋ก ๋๋ฌ๋๋ค๋ ์ฅ์ ์ด ์๋ค. ์ด๋์ ๋ฌด์์ด ์คํจํ ์ ์๋์ง ์จ์ง ์๋๋ค.
Python๊ณผ ๋๋ํ ๋๋ฉด
๊ฐ์ ์ผ์ Python์ ์์ธ๋ก ์ฒ๋ฆฌํ๋ค. ๋์ง๋ ์ชฝ์ raise, ๋ฐ๋ ์ชฝ์ try/except๋ค.
# Python โ ์์ธ๋ก ์ฒ๋ฆฌ
def divide(a, b):
if b == 0:
raise ValueError("0์ผ๋ก ๋๋ ์ ์์")
return a // b
try:
result = divide(10, 0)
print("๊ฒฐ๊ณผ:", result)
except ValueError as e:
print("์คํจ:", e)์ฐจ์ด๋ฅผ ์ ๋ฆฌํ๋ฉด ์ด๋ ๋ค.
| Python | Go | |
|---|---|---|
| ์๋ฌ๋ฅผ ์๋ฆฌ๋ ๋ฒ | raise๋ก ๋์ง | ๋ฐํ๊ฐ์ผ๋ก ๋๋ ค์ค |
| ์๋ฌ๋ฅผ ๋ฐ๋ ๋ฒ | try/except๋ก ๊ฐ์ | if err != nil๋ก ํ์ธ |
| ์ฒ๋ฆฌ ์์น | ํธ์ถ ํ๋ฆ ์ด๋๊ฐ(๋ฉ์ด๋ ๋จ) | ํธ์ถ ์งํ, ๋ฐ๋ก ๊ทธ ์๋ฆฌ |
| ์ ๋ฐ์ผ๋ฉด | ์๋ก ์ ํ๋๋ค ํ๋ก๊ทธ๋จ ์ข ๋ฃ | ๊ทธ๋ฅ ๋ฌด์๋จ(์ปดํ์ผ์ ๋จ) |
๋ง์ง๋ง ์ค์ด ์ค์ํ๋ค. Python์ ์์ธ๋ฅผ ์ ๋ฐ์ผ๋ฉด ๊ฒฐ๊ตญ ํ๋ก๊ทธ๋จ์ด ์ฃฝ์ง๋ง, Go์์ ์๋ฌ๋ ๊ทธ๋ฅ ๊ฐ์ด๋ผ ๋ฌด์ํด๋ ์ปดํ์ผ๋๋ค. ๊ทธ๋์ ์๋ฌ๋ฅผ ํ์ธํ๋ ์ฑ ์์ด ์ ์ ์ผ๋ก ๊ฐ๋ฐ์์๊ฒ ์๋ค.
์๋ฌ๋ฅผ ์๋์ ์ผ๋ก ๋ฒ๋ฆด ๋
์ ๋ง ์๋ฌ๋ฅผ ๋ฌด์ํด๋ ๋๋ ์๋ฆฌ๋ผ๋ฉด
_๋ก ๋ช ์์ ์ผ๋ก ๋ฒ๋ฆฐ๋ค.result, _ := divide(10, 2)์ฒ๋ผ ์ฐ๋ฉด โ์๋ฌ๋ฅผ ๋ดค๊ณ ์ผ๋ถ๋ฌ ์ ์ด๋คโ๋ ์๋๊ฐ ์ฝ๋์ ๋จ๋๋ค. ์๋ฌด ํ์ ์์ด ํ๋ ค๋ณด๋ด๋ ๊ฒ๊ณผ ๋ค๋ฅด๋ค.
3. ์ผํฐ๋ฌ ์ค๋ฅ(sentinel error)
๋๋ก๋ ํธ์ถ์๊ฐ ์๋ฌ์ ์ข ๋ฅ๋ฅผ ๊ตฌ๋ถํด์ ๋ค๋ฅด๊ฒ ์ฒ๋ฆฌํด์ผ ํ๋ค. โ์ฐพ๋ ๊ฒ ์์ด์ ์คํจโ์ โ๊ถํ์ด ์์ด์ ์คํจโ๋ ๋์์ด ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ด๋ค. ์ด๋ด ๋ ์ฐ๋ ๊ฒ ์ผํฐ๋ฌ ์ค๋ฅ, ๋ฏธ๋ฆฌ ์ ์ํด๋ ๋ํ ์๋ฌ ๊ฐ์ด๋ค.
var ErrNotFound = errors.New("not found")
func lookup(id int) (string, error) {
name, ok := db[id]
if !ok {
return "", ErrNotFound // ๋ฏธ๋ฆฌ ์ ์ํ ๊ทธ ๊ฐ์ ๊ทธ๋๋ก ๋ฐํ
}
return name, nil
}ErrNotFound๋ ํจํค์ง ๋ ๋ฒจ์ ํ ๋ฒ ์ ์ธํด๋๊ณ ๊ณ์ ์ฌ์ฌ์ฉํ๋ค. ์ด๋ฆ ์์ Err์ ๋ถ์ด๋ ๊ฒ ๊ด๋ก๋ค(ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ io.EOF, sql.ErrNoRows๊ฐ ์ด๋ฐ ์์ด๋ค).
์ผํฐ๋ฌ์ "ํ์ "์ด ์๋๋ผ "๊ฐ"์ด๋ค
์ผํฐ๋ฌ ์ค๋ฅ๋ ์ ํ์ ์ ๋ง๋๋ ๊ฒ ์๋๋ค.
errors.New๋ก ๋ง๋ ํ๋ฒํ ์๋ฌ ๊ฐ ํ๋๋ฅผ ํจํค์ง์ ๋ฐ์๋๊ณ , ๊ทธ ๊ฐ ์์ฒด๋ฅผ ์ข ๋ฅ์ ํ์์ผ๋ก ์ฐ๋ ๊ฒ๋ฟ์ด๋ค. ๊ทธ๋์ ๋ด๊ธฐ๋ ์ ๋ณด๋ โ์ด ์ข ๋ฅ๊ฐ ์ผ์ด๋ฌ๋คโ๊ฐ ์ ๋ถ๋ค. โ์ด๋ค ํค๋ฅผ ๋ชป ์ฐพ์๋์งโ ๊ฐ์ ๋ถ๊ฐ ๋ฐ์ดํฐ๊น์ง ๋ค๊ณ ๊ฐ์ผ ํ๋ค๋ฉด ๊ฐ ํ๋๋ก๋ ๋ถ์กฑํ๊ณ , ๊ทธ๋๋ 4ยท5๋ฒ์์ ๋ค๋ฃฐ ์ปค์คํ ์๋ฌ ํ์ (errors.As๋ก ๊บผ๋ด ์ฐ๋)์ผ๋ก ๋์ด๊ฐ๋ค.
ํธ์ถ์๋ ์ด ๊ฐ๊ณผ ๋น๊ตํด์ โ์ฐพ๋ ๊ฒ ์๋ ๊ฒฝ์ฐโ๋ง ๋ฐ๋ก ์ฒ๋ฆฌํ๋ค.
name, err := lookup(42)
if errors.Is(err, ErrNotFound) {
fmt.Println("๊ทธ๋ฐ ID ์์, ๊ธฐ๋ณธ๊ฐ ์ฌ์ฉ")
name = "guest"
} else if err != nil {
return err // ๋ค๋ฅธ ์๋ฌ๋ ์๋ก ์ ํ
}๋ฌธ์์ด ๋น๊ต๋ ๊ธ์ง
์ฌ๊ธฐ์ ๊ฐ์ฅ ์ค์ํ ๊ท์น ํ๋. ์๋ฌ๋ฅผ ๋ฉ์์ง ๋ฌธ์์ด๋ก ๋น๊ตํ๋ฉด ์ ๋๋ค.
// ํ์ง ๋ง ๊ฒ โ ๋ฉ์์ง๊ฐ ์กฐ๊ธ๋ง ๋ฐ๋์ด๋ ๊นจ์ง๋ค
if err.Error() == "not found" {
// ...
}๋ฉ์์ง๋ ์ฌ๋์ด ์ฝ์ผ๋ผ๊ณ ์๋ ๊ฒ์ด์ง ํ๋ก๊ทธ๋จ์ด ๋ถ๊ธฐํ๋ผ๊ณ ์๋ ๊ฒ ์๋๋ค. ์คํ๋ฅผ ๊ณ ์น๊ฑฐ๋ ๋ฌธ๊ตฌ๋ฅผ ๋ค๋ฌ๋ ์๊ฐ ๋น๊ต๊ฐ ๊นจ์ง๋ค. ๋์ errors.Is(err, ErrNotFound)๋ก ๊ฐ ์์ฒด๋ฅผ ๋น๊ตํ๋ค(๋ค์ ์น์
์์ errors.Is๋ฅผ ์์ธํ ๋ณธ๋ค).
๋ชจ๋ ์๋ฌ๋ฅผ ์ผํฐ๋ฌ๋ก ๋ง๋ค ํ์๋ ์๋ค
์ผํฐ๋ฌ์ ํธ์ถ์๊ฐ ๊ทธ ์ข
๋ฅ๋ฅผ ๋ณด๊ณ ๋ถ๊ธฐํด์ผ ํ ๋๋ง ๋ง๋ ๋ค. ๊ทธ๋ฅ ์๋ก ์ ํํ๋ค ๋ก๊ทธ๋ง ๋จ๊ธธ ์๋ฌ๋ผ๋ฉด fmt.Errorf๋ก ๋ง๋ ์ผ๋ฐ ์๋ฌ๋ก ์ถฉ๋ถํ๋ค. ์ผํฐ๋ฌ์ ๋จ๋ฐํ๋ฉด ํจํค์ง์ ๊ณต๊ฐ API๊ฐ ๋์ด๋๊ณ , ํธ์ถ์๊ฐ ๊ทธ ๊ฐ์ ์์กดํ๊ฒ ๋์ด ๋์ค์ ๋ฐ๊พธ๊ธฐ ์ด๋ ค์์ง๋ค.
Python์ ์์ธ ํด๋์ค์ ๋น๊ต
Python์์ ์๋ฌ ์ข ๋ฅ๋ฅผ ๊ตฌ๋ถํ๋ ๊ฑด ์์ธ ํด๋์ค๋ค.
except FileNotFoundError์ฒ๋ผ ํ์ ์ผ๋ก ์ก๋๋ค. Go์ ์ผํฐ๋ฌ์ ๊ทธ ์๋ฆฌ๋ฅผ ๊ฐ ํ๋๋ก ๋์ ํ๋ ์ ์ด๋ผ, โ์์ธ ํด๋์ค ์์ด ๊ฐ์ผ๋ก ๋ถ๊ธฐํ๋คโ๊ฐ Python ๊ฐ๋ฐ์์๊ฒ ๋ฏ์ค๊ฒ ๋๊ปด์ง ์ ์๋ค.
4. ์ค๋ฅ ๋ํ(wrapping)
์๋ฌ๊ฐ ๊น์ ๊ณณ์์ ์ฌ๋ผ์ฌ ๋, ๊ทธ๋ฅ ๊ทธ๋๋ก ์ ํํ๋ฉด โ์ด๋์ ๋ฌด์์ ํ๋ค ๋ฌ๋์งโ ๋ฌธ๋งฅ์ด ์ฌ๋ผ์ง๋ค. not found๋ผ๋ ๋ฉ์์ง๋ง ๋ด์๋ ์ด๋ ๋จ๊ณ์์ ๋ฌ๋์ง ์ ์ ์๋ค. ๋ํ์ ์๋ณธ ์๋ฌ๋ฅผ ๋ณด์กดํ ์ฑ ๋ฌธ๋งฅ์ ๋ง๋ถ์ด๋ ๋ฐฉ๋ฒ์ด๋ค.
ํต์ฌ์ fmt.Errorf์ %w ๋์ฌ๋ค.
func fileChecker(name string) error {
f, err := os.Open(name)
if err != nil {
return fmt.Errorf("in fileChecker: %w", err) // %w๋ก ์๋ณธ์ ๊ฐ์
}
defer f.Close()
return nil
}%w๋ก ๊ฐ์ธ๋ฉด ์ ์๋ฌ๊ฐ ๋ง๋ค์ด์ง๋, ๊ทธ ์์ ์๋ณธ ์๋ฌ๊ฐ ๊ทธ๋๋ก ๋ค์ด ์๋ค. ๋ฉ์์ง๋ in fileChecker: open data.txt: no such file or directory์ฒ๋ผ ๋ฐ๊นฅ ๋ฌธ๋งฅ๊ณผ ์๋ณธ์ด ์ด์ด์ง ํํ๊ฐ ๋๋ค. ํธ์ถ ๊ฒฝ๋ก๋ฅผ ๋ฐ๋ผ ์ฌ๋ฌ ๋ฒ ๋ํํ๋ฉด โ์ด๋ โ ์ด๋ โ ์ด๋์ ๋ฌ๋คโ๋ ํ๋ฆ์ด ํ ์ค์ ์์ธ๋ค.
%w์ %v์ ์ฐจ์ด
fmt.Errorf์์ ์๋ฌ๋ฅผ ๋ผ์ธ ๋ %w์ %v๋ ๊ฒฐ๊ณผ๊ฐ ๋ค๋ฅด๋ค.
%vโ ์๋ณธ์ ๋ฉ์์ง ํ ์คํธ๋ง ๊ฐ์ ธ๋ค ๋ถ์ธ๋ค. ์๋ณธ ์๋ฌ ๊ฐ์ ๋ฒ๋ ค์ง๋ค.%wโ ์๋ณธ ์๋ฌ ๊ฐ์ ์ฒด์ธ์ ๋ณด์กดํ๋ค. ๋์ค์errors.Is/errors.As๋ก ๊บผ๋ด๋ณผ ์ ์๋ค.
์ข
๋ฅ๋ฅผ ๊ตฌ๋ถํด์ผ ํ ์๋ฌ๋ผ๋ฉด %w๋ก ๊ฐ์ธ ์ฒด์ธ์ ์ ์งํ๊ณ , ๋จ์ํ ๋ฉ์์ง๋ง ๋จ๊ธฐ๋ฉด ๋๋ ๊ฒฝ์ฐ์ %v๋ฅผ ์ด๋ค.
errors.Unwrap โ ํ ๊ฒน ๋ฒ๊ธฐ๊ธฐ
๋ํ๋ ์๋ฌ์์ ๋ฐ๋ก ์์ชฝ ์๋ฌ๋ฅผ ๊บผ๋ด๋ ํจ์๊ฐ errors.Unwrap์ด๋ค. ํ ๋ฒ์ ํ ๊ฒน์ฉ ๋ฒ๊ธด๋ค.
err := fileChecker("missing.txt")
inner := errors.Unwrap(err) // "in fileChecker:" ๋ฅผ ๋ฒ๊ธฐ๊ณ ์์ชฝ ์๋ฌ๋ฅผ ๊บผ๋๋ค๋ง ์ค๋ฌด์์ Unwrap์ ์ง์ ํธ์ถํ ์ผ์ ๋ง์ง ์๋ค. ๋ณดํต์ ๋ค์ ์น์
์ errors.Is/errors.As๊ฐ ๋ด๋ถ์์ ์์์ ์ฒด์ธ์ ๋๊น์ง ํ๋ฉฐ ๊ฒ์ฌํด์ค๋ค.
์ปค์คํ ์๋ฌ ํ์ ์ ์ฒด์ธ์ ์ฐธ์ฌ์ํค๊ธฐ
๋ด๊ฐ ๋ง๋ ์๋ฌ ํ์
๋ Unwrap() error ๋ฉ์๋๋ฅผ ๊ตฌํํ๋ฉด ๋ํ ์ฒด์ธ์ ๋ ์ ์๋ค. ์์ ๊ฐ์ผ ์๋ฌ๋ฅผ ๋๋ ค์ฃผ๋๋ก ์์ฑํ๋ฉด ๋๋ค.
type StatusError struct {
Code int
Err error // ๊ฐ์ผ ์๋ณธ ์๋ฌ
}
func (e StatusError) Error() string {
return fmt.Sprintf("status %d: %v", e.Code, e.Err)
}
func (e StatusError) Unwrap() error {
return e.Err // ์ฒด์ธ์ ๋ค์ ๊ณ ๋ฆฌ๋ฅผ ์๋ ค์ค
}์ด๋ ๊ฒ ํด๋๋ฉด StatusError๋ก ๊ฐ์ผ ์๋ฌ๋ errors.Is/errors.As๊ฐ ์์ชฝ๊น์ง ๋ฐ๋ผ ๋ค์ด๊ฐ ๊ฒ์ฌํ๋ค.
์ธ์ ๋ํํ๋
์๋ฌ๋ฅผ ์๋ก ๊ทธ๋ฅ ํ๋ ค๋ณด๋ผ ๊ฑฐ๋ฉด ๋ํ ์์ด ๊ทธ๋๋ก
return errํด๋ ๋๋ค. ๋ํ์ ํธ์ถ ๊ฒฝ๋ก์ ๋ฌธ๋งฅ์ด ๋๋ฒ๊น ์ ๋์์ด ๋ ๋ ํ๋ค. โ์ด๋ ํจ์์์ ์ด ์๋ฌ๋ฅผ ๋ฐ์๋๊ฐโ๊ฐ ์ถ์ ์ ์๋ฏธ ์๋ ์ง์ ์์๋ง%w๋ก ํ ๊ฒน ๋ง๋ถ์ด๋ ๊ฒ ์ ๋นํ๋ค. ๋ชจ๋ ๋จ๊ณ์์ ๋ฌด์์ ๊ฐ์ธ๋ฉด ๋ฉ์์ง๋ง ๊ธธ์ด์ง๋ค.
5. errors.Is ์ errors.As
๋ํ์ด ์๊ธฐ๋ฉด ๋ฌธ์ ๊ฐ ํ๋ ๋ฐ๋ผ์จ๋ค. ์๋ฌ๊ฐ ์ฌ๋ฌ ๊ฒน์ผ๋ก ๊ฐ์ธ์ง๋ฉด, ๋ฐ๊นฅ๋ง ๋ด์๋ ์์ชฝ์ ๋ฌด์์ด ์๋์ง ๋ชจ๋ฅธ๋ค. ๊ทธ๋์ == ์ง์ ๋น๊ต๋ ํ์
๋จ์ธ(type assertion)์ด ๊ฒ๋ง ๋ณด๊ณ ์คํจํ๋ค.
err := fileChecker("missing.txt") // os.ErrNotExist๋ฅผ in fileChecker๋ก ๊ฐ์
if err == os.ErrNotExist { // false โ ๋ฐ๊นฅ์ fmt๊ฐ ๋ง๋ ๋ค๋ฅธ ๊ฐ์ด๋ค
// ์ฌ๊ธฐ ์ ๋ ์ ๋ค์ด์ด
}์ด ๋ฌธ์ ๋ฅผ ํ์ด์ฃผ๋ ๊ฒ errors.Is์ errors.As๋ค. ๋ ๋ค ์ฒด์ธ์ ๋๊น์ง ๋ฐ๋ผ ๋ค์ด๊ฐ๋ฉฐ ๊ฒ์ฌํ๋ค.
errors.Is โ โ์ด๊ฒ ๋ฐ๋ก ๊ทธ ์๋ฌ์ผ?โ (๊ฐ ๋น๊ต)
errors.Is(err, target)๋ ์ฒด์ธ ์ด๋๊ฐ์ target๊ณผ ๊ฐ์ ๊ฐ์ด ์๋์ง ํ์ธํ๋ค. ์ฃผ๋ก ์ผํฐ๋ฌ ์ค๋ฅ๋ฅผ ์ฐพ์ ๋ ์ด๋ค.
err := fileChecker("missing.txt")
if errors.Is(err, os.ErrNotExist) { // ์ฒด์ธ์ ํ๋ฉฐ os.ErrNotExist๋ฅผ ์ฐพ์ โ true
fmt.Println("ํ์ผ์ด ์์ต๋๋ค")
}๊ฒ์ด ๋ช ๊ฒน์ผ๋ก ๊ฐ์ธ์๋ , ์์ ๊ทธ ์ผํฐ๋ฌ ๊ฐ์ด ๋ค์ด ์์ผ๋ฉด true๋ค. 3๋ฒ์์ โ๋ฌธ์์ด ๋น๊ต ๊ธ์ง, errors.Is๋ก ๋น๊ตโ๋ผ๊ณ ํ ๊ฒ ์ด๊ฒ์ด๋ค.
errors.As โ โ์ด๋ฐ ํ์ ์๋ฌ๊ฐ ์์ด? ์์ผ๋ฉด ๊บผ๋ด์คโ (ํ์ ํ์ธ + ์ถ์ถ)
errors.As(err, &target)๋ ์ฒด์ธ ์์ ํน์ ํ์
์ ์๋ฌ๊ฐ ์๋์ง ํ์ธํ๊ณ , ์์ผ๋ฉด ๊ทธ ๊ฐ์ target์ ๊บผ๋ด ๋ด๋๋ค. ๊ฐ ํ๋๋ฅผ ์ฝ ์ง์ด ์ฐพ๋ Is์ ๋ฌ๋ฆฌ, โ์ด ๋ถ๋ฅ์ ์๋ฌโ๋ฅผ ์ฐพ์ ๊ทธ ์์ ํ๋๊น์ง ๊บผ๋ด ์ธ ๋ ์ด๋ค.
var statusErr StatusError
if errors.As(err, &statusErr) { // ์ฒด์ธ์์ StatusError๋ฅผ ์ฐพ์ผ๋ฉด
fmt.Println("์ํ ์ฝ๋:", statusErr.Code) // ๊บผ๋ธ ๊ฐ์ ํ๋๋ฅผ ์ฌ์ฉ
}As์๋ ๋ฐ์ ๋ณ์์ ์ฃผ์(&statusErr)๋ฅผ ๋๊ธด๋ค. ์ฐพ์ ์๋ฌ๋ฅผ ๊ฑฐ๊ธฐ์ ์ฑ์ ๋ฃ์ด์ผ ํ๊ธฐ ๋๋ฌธ์ด๋ค. ๋ฐํ๊ฐ์ ์ฐพ์๋์ง ์ฌ๋ถ(bool)๋ค.
๋์ ๋๋ํ ์ ๋ฆฌํ๋ฉด
| ๋ฌด์์ ๋ฌป๋ | ๋ฌด์์ ๋๊ธฐ๋ | ์ธ์ ์ฐ๋ | |
|---|---|---|---|
errors.Is(err, target) | โ์ด ๊ฐ์ด ์ฒด์ธ์ ์๋?โ | ๋น๊ตํ ์๋ฌ ๊ฐ | ์ผํฐ๋ฌ ์ค๋ฅ ๊ตฌ๋ถ |
errors.As(err, &target) | โ์ด ํ์ ์ด ์ฒด์ธ์ ์๋? ๊บผ๋ด์คโ | ๋ด์ ๋ณ์์ ์ฃผ์ | ์ปค์คํ ์๋ฌ์ ํ๋ ์ฌ์ฉ |
comma-ok์ฒ๋ผ ์์ ํ๋ค
errors.As๋ 03ํธ์ ๋งต ์กฐํ(v, ok := m[k])๋ ํ์ ๋จ์ธ์ comma-ok ํํ์ ๋ฎ์๋ค. ์ฐพ์ผ๋ฉด ๊ฐ์ ์ฑ์ฐ๊ณtrue, ๋ชป ์ฐพ์ผ๋ฉด ๊ทธ๋๋ก ๋๊ณfalse๋ฅผ ์ค๋ค. ํจ๋ ์์ด โ์์ผ๋ฉด ์ฐ๊ณ , ์์ผ๋ฉด ๋ถ๊ธฐโ๊ฐ ๊น๋ํ๊ฒ ๋๋ค. ๋ํ๋ ์๋ฌ๋ฅผ ๋ค๋ฃฐ ๋๋ ์ง์ ==๋ ๋จ์ธ์ ์ฐ์ง ๋ง๊ณ ๊ฑฐ์ ํญ์Is/As๋ฅผ ์ด๋ค๊ณ ๋ณด๋ฉด ๋๋ค.
6. panic๊ณผ recover
์ง๊ธ๊น์ง ๋ณธ ์๋ฌ๋ ์ ๋ถ โ๊ฐโ์ด์๋ค. ํจ์๊ฐ ์ ์์ ์ผ๋ก ๋ฐํํ๊ณ , ํธ์ถ์๊ฐ ์ฒ๋ฆฌํ ์ ์๋ ๋ฌธ์ ๋ค. ๊ทธ๋ฐ๋ฐ ๊ณ์ ์คํํ๋ ๊ฒ ์์ฒด๊ฐ ์ํํ ์ํฉ์ด ๋ฐ๋ก ์๋ค. ํ๋ก๊ทธ๋จ ์ํ๋ฅผ ๋ ์ด์ ๋ฏฟ์ ์ ์๋ ๊ฒฝ์ฐ๋ค. ์ด๋ด ๋ ์ฐ๋ ๊ฒ panic์ด๋ค.
func mustParseConfig(path string) Config {
data, err := os.ReadFile(path)
if err != nil {
panic("ํ์ ์ค์ ํ์ผ์ ์ฝ์ ์ ์์: " + err.Error())
}
// ...
}panic์ด ๋ฐ์ํ๋ฉด ๋ณดํต์ ์๋ฌ์ ๋ค๋ฅด๊ฒ ๋์ํ๋ค.
- ํ์ฌ ํจ์์ ์คํ์ด ์ฆ์ ๋ฉ์ถ๋ค
- ์์ฌ ์๋
defer๋ค์ ๊ทธ๋๋ ์คํ๋๋ค(์์ ์ ๋ฆฌ๋ ๋ณด์ฅ๋๋ค) - ๊ทธ ํจ์๋ฅผ ํธ์ถํ ์๋ก ๊ฑฐ์ฌ๋ฌ ์ฌ๋ผ๊ฐ๋ฉฐ ๊ฐ์ ์ผ์ ๋ฐ๋ณตํ๋ค
- ๋๊น์ง ์๋ฌด๋ ๋ง์ง ๋ชปํ๋ฉด ํ๋ก๊ทธ๋จ์ด ์ข ๋ฃ๋๊ณ ์คํ ํธ๋ ์ด์ค๊ฐ ์ถ๋ ฅ๋๋ค
recover โ defer ์์์ panic์ ์์ต
recover๋ ์งํ ์ค์ธ panic์ ๋ฉ์ถ๊ณ ํ๋ก๊ทธ๋จ์ ์ ์ ํ๋ฆ์ผ๋ก ๋๋๋ฆฐ๋ค. ๋จ, defer๋ก ๋ฏธ๋ฃฌ ํจ์ ์์์๋ง ์๋ํ๋ค(05ํธ์ defer์ ์ด์ด์ง๋ค). panic์ด defer๋ฅผ ์คํ์ํค๋ ์ฑ์ง์ ์ด์ฉํ๋ ๊ฒ์ด๋ค.
func safeRun() (err error) {
defer func() {
if r := recover(); r != nil { // panic์ ์ก์๋
err = fmt.Errorf("ํจ๋ ๋ณต๊ตฌ: %v", r) // ์๋ฌ๋ก ๋ณํํด ๋ฐํ
}
}()
riskyOperation() // ์ฌ๊ธฐ์ panic์ด ๋๋
return nil // recover๊ฐ ์ก์์ ์ ์ ๋ฐํ์ผ๋ก ๋ฐ๊ฟ
}์ฌ๊ธฐ์ 05ํธ์ ๋ช
๋ช
๋ ๋ฐํ๊ฐ(named return value)์ด ํจ๊ป ์ฐ์ธ๋ค. recover๋ก ์ก์ ๊ฐ์ err์ ๋ด์ผ๋ฉด, defer๊ฐ ๋๋ ๋ค ๊ทธ err์ด ์ต์ข
๋ฐํ๊ฐ์ด ๋๋ค. panic์ ์ผ๋ฐ ์๋ฌ๋ก ๋ฐ๊ฟ ํธ์ถ์์๊ฒ ์ ์์ ์ผ๋ก ๋๋ ค์ฃผ๋ ํจํด์ด๋ค.
๊ธฐ์ค: error๋ panic์ด๋
๋์ ๊ฐ๋ฅด๋ ๊ธฐ์ค์ ๋ช ํํ๋ค.
| error | panic | |
|---|---|---|
| ์ด๋ค ์ํฉ | ํธ์ถ์๊ฐ ์ ์ ์ฒ๋ฆฌ ๊ฐ๋ฅํ ๋ฌธ์ | ๊ณ์ ์คํํ๋ฉด ํ๋ก๊ทธ๋จ ์ํ๋ฅผ ๋ฏฟ์ ์ ์๋ ๋ฌธ์ |
| ์์ | ํ์ผ ์์, ์๋ชป๋ ์ ๋ ฅ, ๋คํธ์ํฌ ์คํจ | ํ๋ก๊ทธ๋๋จธ ๋ฒ๊ทธ, ๋ถ๋ณ์(invariant) ์๋ฐ, ์ด๊ธฐํ ์คํจ, ๋๋ฌ ๋ถ๊ฐ ๊ฒฝ๋ก |
| ํ๋ฆ | ์๋ ์ ์ง ์์, ๋ฐํ๊ฐ์ผ๋ก ์๋ฆผ | ์คํ ๊ฐ์ ์ค๋จ, ์๋ก ์ ํ |
| ๋ง์ง ์์ผ๋ฉด | ๊ทธ๋ฅ ๋ฌด์๋จ | ํ๋ก๊ทธ๋จ ์ข ๋ฃ + ์คํ ํธ๋ ์ด์ค |
์ค๋ฌด ๊ธฐ์ค์ ๋จ์ํ๋ค. ํธ์ถ์๊ฐ ํฉ๋ฆฌ์ ์ผ๋ก ๋์ํ ์ ์๋ ๋ฌธ์ ๋ฉด error, ๊ทธ๋ ์ง ์๊ณ โ์ฌ๊ธฐ๊น์ง ์๋ค๋ ๊ฒ ์์ฒด๊ฐ ๋ฒ๊ทธโ์ธ ๋ฌธ์ ๋ฉด panic. ๋๋ถ๋ถ์ ์ผ์์ ์ธ ์คํจ๋ error๋ก ์ฒ๋ฆฌํ๊ณ , panic์ ์ ๋ง ์์ธ์ ์ธ ์ํฉ์๋ง ๋จ๊ฒจ๋๋ค.
Python ์์ธ์์ ๊ฒฐ์ ์ ์ฐจ์ด
Python์์ ์์ธ๋ ์ผ์์ ์ธ ํ๋ฆ ์ ์ด์๋ ์ฐ์ธ๋ค. ๋ฐ๋ณต์๊ฐ ๋๋๋ฉด StopIteration์ ๋์ง๊ณ , ํค๊ฐ ์์ผ๋ฉด KeyError๋ฅผ ๋์ง๋ค. try/except๋ก ํ๋ฆ์ ๋ถ๊ธฐํ๋ ๊ฒ ํํ ํจํด์ด๋ค.
Go์ panic์ ๊ทธ ๋ฐ๋๋ค. panic์ ๋น์์ฉ์ด๋ค. โํ๋ฆ ์ ์ดโ๋ก ์ฐ๋ ๊ฒ ์๋๋ผ, ์ ๋ง ๋ ์งํํ๋ฉด ์ ๋ ๋๋ง ํฐ๋จ๋ฆฐ๋ค. Python์ ์์ธ์ ์ต์ํ๋ค๋ฉด panic์ try/except์ฒ๋ผ ์ฐ๊ณ ์ถ์ ์ ์์ง๋ง, Go์์ ๊ทธ๊ฑด ์ํฐํจํด์ด๋ค. Python์ ์์ธ โ Go์ error์ด๊ณ , Go์ panic์ Python์์ ์ก์ง ์๊ณ ํ๋ก๊ทธ๋จ์ ์ฃฝ๊ฒ ๋๋ ์น๋ช ์ ์์ธ์ ๊ฐ๊น๋ค.
panic์ ํ๋ฆ ์ ์ด๋ก ์ฐ์ง ๋ง ๊ฒ
โ์๋ฌ ๋ฐํ์ด ๊ท์ฐฎ์ผ๋ panic์ผ๋ก ๋์ง๊ณ recover๋ก ๋ฐ์โ๋ ์ ํน์ด ์๋ค. Go์์๋ ๊ถ์ฅ๋์ง ์๋๋ค. panic/recover๋ ํจํค์ง ๊ฒฝ๊ณ๋ฅผ ๋์ง ์๊ฒ ๊ฐ๋๊ณ , ๊ณต๊ฐ ํจ์๋ ๊ฐ๋ฅํ๋ฉด error๋ฅผ ๋ฐํํ๋๋ก ๋ง๋ ๋ค. ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์์ panic์ ์ฐ๋๋ผ๋, ๊ฒฝ๊ณ์์ recover๋ก ์ก์ error๋ก ๋ฐ๊ฟ ๋ด๋ณด๋ด๋ ๊ฒ ๊ด๋ก๋ค.
7. defer๋ก ์๋ฌ ๋ํํ๊ธฐ
ํจ์์ return ์ง์ ์ด ์ฌ๋ฌ ๊ฐ์ผ ๋, ๋ชจ๋ ์๋ฌ์ ๋๊ฐ์ ๋ฌธ๋งฅ์ ๋ถ์ด๋ ค๋ฉด ๋งค๋ฒ fmt.Errorf๋ฅผ ๋ฐ๋ณตํด์ผ ํ๋ค. ์ด๊ฑธ ํ ๊ณณ์์ ์ฒ๋ฆฌํ๋ ํจํด์ด ์๋ค. ๋ช
๋ช
๋ ๋ฐํ๊ฐ(named return value) ๊ณผ defer ํด๋ก์ ๋ฅผ ์กฐํฉํ๋ ๊ฒ์ด๋ค.
func loadUser(id int) (err error) { // ๋ฐํ ์๋ฌ์ err๋ผ๋ ์ด๋ฆ์ ์ค
defer func() {
if err != nil {
err = fmt.Errorf("loadUser(%d): %w", id, err) // ๋๊ฐ๋ ์๋ฌ์ ๋ฌธ๋งฅ์ ํ ๋ฒ์ ๋ง๋ถ์
}
}()
if err := validateID(id); err != nil {
return err // ์ฌ๊ธฐ์ ๋๊ฐ๋
}
if err := fetchFromDB(id); err != nil {
return err // ์ฌ๊ธฐ์ ๋๊ฐ๋
}
return nil // nil์ด๋ฉด defer๊ฐ ๊ฑด๋๋ฆฌ์ง ์์
}return err์ด ์ด๋ ์ง์ ์์ ์ผ์ด๋๋ , defer ํด๋ก์ ๊ฐ ๋ง์ง๋ง์ err์ ํ ๋ฒ ๊ฒ์ฌํด ๋ฌธ๋งฅ์ ์
ํ๋ค. loadUser(42): ... ์ ๋์ฌ๊ฐ ๋ชจ๋ ์คํจ ๊ฒฝ๋ก์ ์๋์ผ๋ก ๋ถ๋๋ค. 05ํธ์์ ๋ณธ โdefer๋ก ๋ช
๋ช
๋ ๋ฐํ๊ฐ ์์ โ์ด ์๋ฌ ์ฒ๋ฆฌ์์ ์ด๋ ๊ฒ ํ์ฉ๋๋ค.
๊ณผํ๋ฉด ๊ฐ๋ ์ฑ์ ํด์น๋ค
์ด ํจํด์ return ์ง์ ์ด ๋ง๊ณ ๋ฌธ๋งฅ์ด ๊ณตํต์ผ ๋ ์ ์ฉํ์ง๋ง, ๋จ์ฉํ๋ฉด ์๋ฌ๊ฐ ์ด๋์ ์ด๋ป๊ฒ ๊ฐ๊ณต๋๋์ง ํ๋์ ์ ๋ค์ด์จ๋ค. return์ด ํ๋ ๊ฐ๋ฟ์ด๋ผ๋ฉด ๊ทธ๋ฅ ๊ทธ ์๋ฆฌ์์
fmt.Errorf("...: %w", err)๋ก ๊ฐ์ธ๋ ๊ฒ ๋ ์ฝ๊ธฐ ์ฝ๋ค. defer ๋ํ์ โ๊ณตํต ๋ฌธ๋งฅ์ ํ ๋ฒ์ ๋ถ์ผ ๊ฐ์น๊ฐ ์์ ๋โ๋ง ์ด๋ค.
Python ๊ฐ๋ฐ์๋ฅผ ์ํ ํ ์ค ์์ฝ
Go์์ ์๋ฌ๋ ๋์ง๊ณ ๋ฐ๋ ์์ธ๊ฐ ์๋๋ผ, ๋ฐํํ๊ณ ํ์ธํ๋ ๊ฐ์ด๋ค.
if err != nil์ด ๋ฐ๋ณต๋ผ๋, ์คํจ ๊ฐ๋ฅํ ๋ชจ๋ ์ง์ ์ด ์ฝ๋์ ๋๋ฌ๋๋ค๋ ๊ฒ ์ด ๋ฐฉ์์ ํต์ฌ์ด๋ค. panic์ ๊ทธ ๊ท์น์ ์์ธ๊ฐ ์๋๋ผ, ๊ท์น์ด ํตํ์ง ์๋ ๋น์ ์ํฉ ์ ์ฉ์ผ๋ก๋ง ๋จ๊ฒจ๋๋ค.