Golang, ๊ทธ๋๋ค์ ์ด๋ป๊ฒ ํ ๊ฒ์ธ๊ฐ - 1. ๋ค์ด๊ฐ๋ฉฐ
Golang, ๊ทธ๋๋ค์ ์ด๋ป๊ฒ ํ ๊ฒ์ธ๊ฐ - 1. ๋ค์ด๊ฐ๋ฉฐ ๊ด๋ จ
์๋ ํ์ธ์, ๋ง 2๋ ์ฐจ ๊ฐ๋ฐ์๋ก ํด๋ก๋ฐ๋ ธํธ ์๋ฒ๋ฅผ ๊ฐ๋ฐํ๊ณ ์๋ ๊น์คํ์ ๋๋ค. ์ด ๊ธ์ ์๋ฆฌ์ฆ์์๋ ํด๋ก๋ฐ๋ ธํธ V2๋ฅผ ๊ฐ๋ฐํ๋ฉฐ ํ ๋ด๋ถ ์ฝ๋ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ ํ ์ด์ผ๊ธฐ๋ฅผ ํด๋ณด๋ ค ํฉ๋๋ค. ์ต๋ํ ๋๊ตฌ๋ ์ดํดํ๊ธฐ ์ฝ๊ฒ ์ค๋ช ํ๋ ค ๋ ธ๋ ฅํ์ง๋ง ์ฝ๋์ ๋ํ ๋ด์ฉ์ด ์ด๋ ์ ๋ ์๋ค ๋ณด๋ Golang์ ํ ๋ฒ์ด๋ผ๋ ์ ํด๋ณด์ ๋ถ์ด๋ฉด ์ข ๋ ์ดํดํ๊ธฐ ์ฌ์ธ ๊ฒ ๊ฐ์ต๋๋ค.
๋ฏธ์ผ์ํค ํ์ผ์ค ๊ฐ๋ ์ ์ํ โ๊ทธ๋๋ค์ ์ด๋ป๊ฒ ์ด ๊ฒ์ธ๊ฐโ๋ฅผ ์์๋์?
ํธ๋ถํธ๊ฐ ๊ฐ๋ฆฌ๋ ์ํ์ง๋ง ์ ๋ ์ฆ๊ฒ๊ฒ ๊ด๋ํ์ต๋๋ค. ์ด๋ ํ ์ ๋ต์ ์ง์ ๊ด๊ฐ์๊ฒ ์ฃผ๋ ค๊ณ ํ์ง ์๊ณ ๋ณธ์ธ์ ์ถ์ ํ์ด๋ธ ํ๊ณ ๋ก ๊ฐ์ ์ํ์์ต๋๋ค. โ๋๋ ์ด๋ ๊ฒ ์ด์๊ณ , ์ด๋ฐ ๊ฒ์ ํํํ๊ณ ๊นจ๋ฌ์๋๋ฐ, ๊ทธ๋์ ๊ทธ๋๋ค์ ์ด๋ป๊ฒ ์ด ๊ฒ์ธ๊ฐ์?โ ์ด๋ ๊ฒ ์ง๋ฌธ์ ๋์ง๋ ๋ฏํ์ต๋๋ค.
๋ง์ต๋๋ค. ์ํ ์ ๋ชฉ์ ๋ณํํด์ ์ด ๊ธ์ ์ ๋ชฉ์ ์ง์ด๋ณด์์ต๋๋ค. ์ ๊ฐ ํ์ฌ ํ์์ ์ฒ์์ผ๋ก Golang์ ์ ํ๊ณ Golang์ผ๋ก API ์๋ฒ๋ฅผ ๊ฐ๋ฐํ๋ฉด์ ๊ฒช์๋ ๊ณ ๋ฏผ๊ณผ ๊ฒฐ๊ณผ๋ฌผ์ ์ฌ๋ ค๋ถ๊ป ์๊ฐํ๋ ค ํฉ๋๋ค. ์ ๊ฐ ์ํ ์ ๋ชฉ์ ๋ณํํ๋ฏ์ด ์ด ๊ธ์ ๋ด์ฉ์ ์ ์ ๊ฐ๋ฐ ์ผ๋๊ธฐ์ ๋๋ค. ์ฌ๋ฌ๋ถ์ด โ์ด ์ฌ๋์ ์ด๋ฐ ์๊ฐ์ ํ๊ณ ์ด๋ ๊ฒ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ตฌ๋โ ํ๋ฉฐ ์ฝ์ด์ฃผ์๋ฉด ์ข๊ฒ ์ต๋๋ค.
์์ํ๊ธฐ ์ ์
๊ธ์ ์์ํ๊ธฐ ์์, ์ ๊ฐ ๊ณ ๋ฏผํ๋ ๋ถ๋ถ์ด ๋ ์ ์ดํด๋๋๋ก Golang์ ๋ช ๊ฐ์ง ํน์ง๊ณผ ์ปจ๋ฒค์ ์ ์๊ฐํ๊ฒ ์ต๋๋ค.
Don't panic
Golang์ ์ฒ์ ์ ํ ์ฌ๋๋ค์๊ฒ ๊ฐ์ฅ ํฌ๊ฒ ๋์ ๋๋ ๋ถ๋ถ์ error์ ๊ดํ ๋ถ๋ถ์
๋๋ค. Java ๊ฐ์ ์ธ์ด๋ ์์ธ(exception)๋ฅผ try
/catch
๋ก ์ฒ๋ฆฌํ๋ ๋ฐฉ์์ ์ฌ์ฉํ์ง๋ง Golang์๋ try/catch๊ฐ ์์ต๋๋ค. try/catch์ ๋น์ทํ panic/recover๊ฐ ์๊ธฐ๋ ํ์ง๋ง, Golang์๋ Don't panic์ด๋ผ๋ ๊ฐ์ฅ ์ค์ํ ์ปจ๋ฒค์
์ด ์์ต๋๋ค. error๋ฅผ ์ฒ๋ฆฌํ ๋๋ panic
์ ์ฌ์ฉํ์ง ๋ง๊ณ error
์์ฒด๋ฅผ ๋ฐํํ๋ผ๋ ๊ฒ์
๋๋ค.
func openFile(fn string) error {
f, err := os.Open(fn)
if err != nil {
return err
// panic(err) // don't panic!
}
defer f.Close()
return nil
}
func main() {
// ์๋ชป๋ ํ์ผ๋ช
์ ๋ฃ์
if err := openFile("Invalid.txt"); err != nil {
fmt.Println(err)
}
}
panic์ ํ๋ก๊ทธ๋จ์ด ์ข ๋ฃ๋์ด์ผ ๋ง๋ ํ ์ํฉ(stackoverflow, OOM ๋ฑ)์๋ง ์ฌ์ฉ๋์ด์ผ ํ๋ฉฐ recover๋ฅผ ํตํด ํ๋ก๊ทธ๋จ์ ๋์ด๋ฆด ์ ์์ต๋๋ค.
Errors are value
panic์ด ์ฌ์ฉ๋์ด์ผ ํ๋ ์ํฉ์ ์ ์ธํ๋ฉด error๋ฅผ ๊ฐ์ผ๋ก ์ทจ๊ธํ๋ ์ ๊ทผ ๋ฐฉ์์ ์ทจํฉ๋๋ค.
Values can be programmed, and since errors are values, errors can be programmed.
์ถ์ฒ: The Go Blog
๊ฐ(value)์ ๋ณ์๋ ์์์ ํ ๋นํ๊ฑฐ๋ ์กฐ์์ด ๊ฐ๋ฅํ๋ฉฐ, error ๋ํ ๊ฐ์ด๋ฏ๋ก ๋ณ์๋ ์์์ ํ ๋น์ด ๊ฐ๋ฅํฉ๋๋ค.
var ErrDivideByZero = errors.New("divide by zero")
func Divide(a, b int) (int, error) {
if b == 0 {
return 0, ErrDivideByZero
}
return a / b, nil
}
func main() {
result, err := Divide(10, 0)
if err != nil {
log.Error(err) // "divide by zero"
return
}
fmt.Printlnt(result)
}
Import library by repository path
Golang์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฝ๊ฒ ๋ฐฐํฌํ๊ณ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค. GitHub ์ ์ฅ์ URL ์์ฒด๊ฐ ๊ฐ์ ธ์ค๊ธฐ ๊ฒฝ๋ก๊ฐ ๋๊ณ GitHub์ release ํ๊ทธ๋ง ๋ง๋ค๋ฉด ๋ฉ๋๋ค.
๋ค์ ๋ช ๋ น์ผ๋ก ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ถ๊ฐํ ์ ์์ต๋๋ค.
go get -u github.com/gin-gonic/gin
์ ๋ช
๋ น์ ์คํํ๋ฉด Golang ์ ํ๋ฆฌ์ผ์ด์
์ ์์กด์ฑ์ ๊ด๋ฆฌํ๋ go.mod
ํ์ผ์ ๋ค์๊ณผ ๊ฐ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ถ๊ฐ๋ฉ๋๋ค.
// go.mod
module ...
go 1.20
require (
github.com/gin-gonic/gin v1.9.1
go.mongodb.org/mongo-driver v1.12.1
...
)
์ด๋ ๊ฒ ๋ณ๋์ ํน์ ๊ณต๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ฐฐํฌํ์ง ์์๋ ์ฝ๊ฒ ๊ฐ๋ฐํ๊ณ ์ฌ์ฉํ ์ ์๋ค๋ ์ฅ์ ์ด ์์ต๋๋ค. ๊ทธ๋์ ์ ํฌ ํ์์๋ Golang์์ ๊ณตํต์ ์ผ๋ก ์ฌ์ฉํ๋ ์ฝ๋๋ฅผ ๋ณ๋์ ๊ณตํต ์ ์ฅ์์์ ๊ฐ๋ฐํ์ฌ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. ์์ผ๋ก ์๊ฐํ ์ฝ๋๋ ๋๋ถ๋ถ ํด๋น ๊ณตํต ์ ์ฅ์์์ ๊ฐ๋ฐํ ๋ด์ฉ์ ๋๋ค.
๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ถ์กฑ
Golang์ ๋ ํ๋์ ํน์ง์ ์ง์ ๊ฐ๋ฐํด์ผ ํ๋ ๋ถ๋ถ์ด ๋ง๋ค๋ ๊ฒ์ ๋๋ค. Java์ ๊ฐ์ ๋ค๋ฅธ ์ธ์ด์ ๋นํด์ ์คํ ์์ค๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๋ง์ด ๋ถ์กฑํฉ๋๋ค.
๋จ์ ์ธ ์๋ก, Golang ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ slice(=List)์์ ๋งจ ๋ง์ง๋ง ์์๋ฅผ ๋นผ๋ด๋ pop ๋ฉ์๋๊ฐ ๋ด์ฅ๋์ด ์์ง ์๋ค๋ ์ ์ด ์์ต๋๋ค. ๋ค์๊ณผ ๊ฐ์ด ๋งจ ๋ง์ง๋ง ์์๋ฅผ ์ง์ ๊บผ๋ด๊ณ ๊ทธ ์๊น์ง์ slice๋ฅผ ์ฌ์ ์ํ๋ pop์ ์ง์ ๊ตฌํํด์ผ ํฉ๋๋ค.
pop, s1 := s[len(s)-1], s[:len(s)-1]
fmt.Println(s1) // [1 2 3 4]
fmt.Println(pop) // 5
๋ํ, Set ์๋ฃ ๊ตฌ์กฐ๊ฐ ์์ด ์ด๋ฅผ map์ผ๋ก ๊ตฌํํด์ผ ํฉ๋๋ค. ์ด๋ ๊ฒ ์ง์ ๊ฐ๋ฐํด์ผ ํ๋ ๋ถ๋ถ์ด ๋ง์, ์๋ชปํ๋ฉด ์ฝ๋ ์์ด ์ฆ๊ฐํ๊ณ ์ค๋ณต ์ฝ๋๊ฐ ์ฝ๊ฒ ์์ฐ๋ ์ ์์์ต๋๋ค.
error๊ฐ ์์์ฌ๋ฆฐ ์์ ๊ณต
panic์ ๋์ง์ง ์๊ณ error๋ฅผ ์์ ํจ์๋ก ์ฌ๋ฆฌ๋ ๊ฒ์ ๋ณด๊ธฐ์๋ ๊ฐ๋จ ๋ช ๋ฃํ ์ปจ๋ฒค์ ์ธ ๊ฒ ๊ฐ์ง๋ง, ์ด๋ ์ ๋ ๋ง๋งํ์ง ์์์ต๋๋ค. 2023๋ Golang ์ฌ์ฉ์ ์ค๋ฌธ์ ๋ฐ๋ฅด๋ฉด ์ด ์ ์ ์ ๋ฟ๋ง ์๋๋ผ Golang ๊ฐ๋ฐ์๋ค์ด ๊ณตํต์ ์ผ๋ก ๊ฐ์ง๋ ์ด๋ ค์์ผ๋ก ๋ณด์ ๋๋ค.
Error handling and learning are respondents' top challenges
ํจ์๊ฐ ํจ์๋ฅผ ๋ถ๋ฅด๊ณ error๋ฅผ ๋ฐํ๋ฐ๊ณ ๋ ๋ฐํํ๋ ๊ตฌ์กฐ๊ฐ ์ฌ์ฌ์น ์๊ฒ ๋ฐ์ํ๋ค ๋ณด๋, ์ด error์ ๋ํ ๋ก๊ทธ๋ ์ด๋์์ ๋จ๊ฒจ์ผ ํ๋๊ฐ์ ๋ํ ์๋ฌธ์ด ๋ค๊ธฐ๋ ํฉ๋๋ค.
ํด๋ก๋ฐ๋ ธํธ V1 ์ฝ๋ ๊ฐ์ ํ์ ์ฌํญ
๊ทธ๋ผ ๊ธฐ์กด V1 ์ฝ๋์์๋ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ๊ณ ์์๋์ง ๊ฐ๋จํ ๊ตฌ์กฐ๋ก ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์ฝ๋ ์
// Controller
func DoAPI() {
result, code := service.DoSomething()
if code == 500 {
log.error("error in main, message: %s", err.Error())
// create err response
return
} else if code != 0 {
log.warn("error in main, message: %s", err.Error())
// create err response
return
}
//...
// create response
}
// Service
func DoSomething() (Foo, int) {
result, code, err := db.DoSomething()
if code != 0 {
log.error("error in baz, message: %s", err.Error())
return result, code
}
// ...
return result, code
}
// DB
func DoSomething() (Foo, int, error) {
cursor, err := doQuery()
if err != nil {
log.error("error in bar, message: %s", err.Error())
return nil, 500, err
}
// decodeCursor()
return result, 0, nil
}
// DB common
func doQuery() (*mongo.Cursor, error) {
// ... do DB query
return nil, errors.New("error")
}
Mongo ๋์ ๋ฐฉ์ ์์ด
์๋ฒ๋ง๋ค Mongo ๋๋ผ์ด๋ฒ๋ฅผ ๊ฐ๊ฐ ๋ํํ์ฌ ์ฌ์ฉํ๊ณ ์์๋๋ฐ, >์๋ฒ๋ง๋ค ๊ตฌํ ๋ฐฉ์์ด ๋ฌ๋์ต๋๋ค. ์๋ฅผ ๋ค์ด FindOne
์์ (result, error)
ํ์์ผ๋ก ๋ฐํํ ๋, A ์๋ฒ๋ ๊ฒฐ๊ณผ ๊ฐ์ด ์์ผ๋ฉด (nil, nil)
์ ๋ฐํํ๊ณ B ์๋ฒ๋ (nil, not found err)
๋ฅผ ๋ฐํํ๋ ๋ฑ ๋ค๋ฅด๊ฒ ๋์ํ์ต๋๋ค.
error ์ฒ๋ฆฌ ๋ฐ ๋ก๊น
์์ ํจ์์์ ์ฝ๊ฒ ์ค๋ฅ๋ฅผ ๊ตฌ๋ถํ ์ ์๋๋ก >error์ ํจ๊ป error code๋ฅผ ์ฌ์ฉํ๊ณ , ๋๋ฒ๊น ์ ์ํด ๋ก๊ทธ ๋ ๋ฒจ์ ์กฐ์ ํ๋ฉฐ >๋ชจ๋ ์ง์ ์์ error ๋ก๊ทธ๋ฅผ ๋จ๊ฒผ์ต๋๋ค. ํ์ง๋ง ์ด๋ ์ปจ๋ฒค์ ์ ๋ง์ง ์๋ ๋ฐฉ์์ด์๊ณ ์ค๋ณต ๋ก๊ทธ๊ฐ ๋ง์์ง๋ ๋ฌธ์ ๊ฐ ์์์ต๋๋ค.
๋ํ, error์ ๋ก๊ทธ ๋ ๋ฒจ์ด ๋ชจํธํ ๊ฒฝ์ฐ๋ ๋ง์์ต๋๋ค. ์๋ฅผ ๋ค์ด, DB ๋ ์ด์ด ํจ์์์ ์ด๋ค document๋ฅผ ์ฐพ์ง ๋ชปํ์ ๋ ์ด๋ Error ๋ ๋ฒจ์ผ๊น์, Info ๋ ๋ฒจ์ผ๊น์? ์ด ์ํฉ์ด ๋ฐ์ํ๋ฉด ์ ๋๋ ์ํฉ์ธ์ง ์ ์์ ์ธ ์ํฉ์ธ์ง๋ ์์ ๋ ์ด์ด์์ ๊ฒฐ์ ๋๋ฏ๋ก ํด๋น ํจ์ ๋ด๋ถ์์๋ ์ ์๊ฐ ์์์ต๋๋ค.
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด, >error๋ฅผ ์ด๋๊น์ง ์ฌ๋ ค์ผ ํ๋ฉฐ ํ์ ๋ ์ด์ด์์ ๋ฐ์ํ error๋ฅผ ์์ ๋ ์ด์ด์์ ์ด๋ป๊ฒ ์ ์ ์์์ง ๊ณ ๋ฏผ์ด ํ์ํ์ต๋๋ค.
๋ง์น๋ฉฐ
๊ณ ๋ฏผ์ ๊ฒฐ๊ณผ๋ฌผ์ ํด๋ก๋ฐ๋ ธํธ V2 ์ฝ๋์ ๋ฐ์ํ์ฌ ์์ ๋ฌธ์ ์ ๋ค์ ํด๊ฒฐํ๋ ค ํ๊ณ , ๊ทธ ๊ณผ์ ์ ๋ํด ์ด์ผ๊ธฐ๋ฅผ ํ์ด๋ด๋ณด๋ ค๊ณ ํฉ๋๋ค.
- error๋ฅผ ์ด๋ป๊ฒ ๋ง๋ค์ด๋๋์ง
- error๋ฅผ ์ด๋ป๊ฒ ์ถ์ฒ ๊ฐ๋ฅํ๋๋ก ์ฌ๋ ค ๋ณด๋๋์ง
- error ํธ๋ค๋ง์ ์ด๋ป๊ฒ ํ๋์ง
์ 3๊ฐ์ง ๊ณ ๋ฏผ์ ์ค์ ์ผ๋ก ์ฝ์ด์ฃผ์๋ฉด ์ข๊ฒ ์ต๋๋ค.