ν¨μ
β μ¬λ¬κ° λ°νκ°
func divmod(a, b int) (int, int) {
return a / b, a % b
}
q, r := divmod(10, 3) // q=3, r=1
β μ΄λ¦ μλ λ°νκ°
func sum(a, b int) (result int) {
result = a + b
return // μ΄λ¦ μμΌλ©΄ return μ λ³μ μλ΅ κ°λ₯
}
β ν¨μλ μΌκΈκ°μ²΄
func operate(a, b int, f func(int, int) int) int {
return f(a, b)
}
sum := func(x, y int) int { return x + y } // λλ€
result := operate(3, 4, sum) // 7
β λλ€(μ΅λͺ
ν¨μ)
result := func(x int) int {
return x * 2
}(5) // 10
β panic & recover
func safeDivide(a, b int) {
defer func() {
if r := recover(); r != nil {
fmt.Println("μλ¬ λ°μ:", r)
}
}()
fmt.Println(a / b) // b=0μΌ κ²½μ° panic
}
β Defer: ν¨μ μ’
λ£μ μ€νλ¨
func writeLog(w io.Writer, message string) {
fmt.Fprintf(w, "[Log] %s\\n", message)
}
func main() {
f, _ := os.Create("app.log")
defer f.Close()
writeLog(f, "File log") // νμΌμ μΆλ ₯
writeLog(os.Stdout, "Console") // μ½μμ μΆλ ₯
}
β κ°λ³ μΈμ ν¨μ
func printArgs(args ...string) {
fmt.Printf("νμ
: %T\\n", args) // []string
for _, arg := range args {
fmt.Println(arg)
}
}
β μ¬λΌμ΄μ€λ₯Ό unpacking ννλ‘ κ°λ³ μΈμ μ λ¬
words := []string{"hello", "world"}
printArgs(words...) // μ¬λΌμ΄μ€ → κ°λ³ μΈμλ‘ μ λ¬ (words... λ°λμ νμ)
β κ³ μ μΈμ + κ°λ³ μΈμ μ‘°ν© κ°λ₯
func log(level string, msgs ...string) {
for _, msg := range msgs {
fmt.Printf("[%s] %s\\n", level, msg)
}
}
log("INFO", "started", "processing") // [INFO] started \\n [INFO] processing
β οΈ μ£Όμμ¬ν
νλͺ© | μ€λͺ |
μΈμκ° 0κ°μΌ μλ μμ | len(nums)λ₯Ό 체ν¬ν΄μΌ μμ |
νμ μ΄ κ³ μ λμ΄μΌ ν¨ | ...interface{}λ₯Ό μ°λ©΄ λͺ¨λ νμ μ λ°μ μ μμ |
μ±λ₯ μ΄μ | ν° λ°°μ΄μ΄λ λΉλ²ν νΈμΆμμλ μ¬λΌμ΄μ€ μμ± λΉμ© κ³ λ € |
π§ λͺ¨λ νμ μμ© μ (interface{})
func logAnything(args ...interface{}) {
for _, a := range args {
fmt.Printf("Value: %v, Type: %T\\n", a, a)
}
}
logAnything(123, "hello", true, 3.14)
β μ£Όμ νΉμ§
νλͺ© | μ€λͺ |
λ€μ€ λ°ν | (T1, T2) ννλ‘ μ¬λ¬ κ° λ°ν κ°λ₯ |
μΌκΈ ν¨μ | λ³μμ μ μ₯, μΈμ/리ν΄κ°μΌλ‘ μ¬μ© κ°λ₯ |
ν΄λ‘μ | λ΄λΆ μν μ μ§ κ°λ₯ |
κ°λ³ μΈμ | ...T λ¬Έλ²μΌλ‘ μ²λ¦¬ |
defer | μ’ λ£ μ§μ μ€ν, 리μμ€ μ 리μ νμ |
panic/recover | μμΈ λ³΅κ΅¬ μ²λ¦¬ |
λ©μλ
β 리μλ²
func (d Dog) info() int {
return d.width * d.height
}
- d Dog λΆλΆμ΄ 리μλ² → info λ©μλλ Dog νμ μ μν¨
- dλ ꡬ쑰체 λ³μλ‘μ¨ ν΄λΉ λ©μλμμ λ§€κ°λ³μμ²λΌ μ¬μ©λ¨
- 리μλ²λ‘λ λͺ¨λ λ‘컬 νμ λ€μ΄ κ°λ₯ν¨ → λ‘컬 νμ μ ν΄λΉ ν¨ν€μ§ μμμ type ν€μλλ‘ μ μΈλ νμ λ€
- λ©μλ μ μλ κ°μ ν¨ν€μ§ λ΄ μ΄λμλ μμΉν μ μμ§λ§ κ΅¬μ‘°μ²΄κ° μ μΈλ νμΌ λ΄μ λ©μλλ μμΉνλ κ²μ΄ μΌλ°μ
- μΌλ° ν¨μλ μ΄λμλ μνμ§ μμ§λ§ λ©μλλ 리μλ²μ μν¨
β ν¬μΈν° λ©μλ vs κ° νμ λ©μλ
package main
import "fmt"
type account struct {
balance int
credit float64
name string
}
func (a *account) withdrawPointer(amount int) {
a.balance -= amount
}
func (a account) withdrawValue(amount int) {
a.balance -= amount
}
func (a account) withdrawReturnValue(amount int) account {
a.balance -= amount
return a
}
func main() {
mainA := account{balance: 100}
fmt.Println(mainA.balance)
mainA.withdrawPointer(10)
fmt.Println(mainA.balance)
mainA.withdrawValue(10)
fmt.Println(mainA.balance)
mainA = mainA.withdrawReturnValue(10)
fmt.Println(mainA.balance)
}
/*
100 μ΄κΈ°κ°
90 ν¬μΈν° λ©μλ
90 κ° λ©μλ
80 κ° λ°ν λ©μλ
*/
β μΈν°νμ΄μ€μ ν¨κ» μ°κΈ°
type Shape interface {
Area() float64
}
type Circle struct {
Radius float64
}
func (c Circle) Area() float64 {
return 3.14 * c.Radius * c.Radius
}
β λ©μλ 체μ΄λ(ν¬μΈν° 리μλ²λ₯Ό 리ν΄ν΄μ 체μ΄λ)
type Builder struct {
data string
}
func (b *Builder) Add(s string) *Builder {
b.data += s
return b
}
func (b *Builder) Result() string {
return b.data
}
res := (&Builder{}).Add("Hello, ").Add("Go!").Result() // "Hello, Go!"
β λ°μ΄ν° μλ
type account struct {
balance int
}
func NewAccount() *account {
return &account{balance: 0}
}
func (a *account) Deposit(amount int) {
if amount > 0 {
a.balance += amount
}
}
func (a *account) Balance() int {
return a.balance
}
// μΈλΆμμ balance μ κ·Ό λΆκ°
β λ©μλμμ μΈν°νμ΄μ€ νμ
μΈμ(λ€νμ±)
type Logger interface {
Log(msg string)
}
type ConsoleLogger struct{}
func (c ConsoleLogger) Log(msg string) {
fmt.Println("[LOG]", msg)
}
func process(l Logger) {
l.Log("Starting process")
}
β μ£Όμ νΉμ§
κ΅¬λΆ | μ€λͺ |
리μλ²(receiver) | λ©μλλ₯Ό μ΄λ€ νμ μ λΆμΌμ§ μ μ |
ν¬μΈν° 리μλ² | μν λ³κ²½ νμ μ μ¬μ© |
κ° λ¦¬μλ² | μ½κΈ° μ μ© μ²λ¦¬ μ μ¬μ© |
체μ΄λ | ν¬μΈν° 리ν΄νλ©΄ κ°λ₯ |
μΈν°νμ΄μ€μ μ¬μ© | λ€νμ± κ΅¬ν κ°λ₯ |
μλ² λ© | μμ μ μ¬ κΈ°λ₯ |
μΈν°νμ΄μ€
β κΈ°λ³Έ
- λ©μλ ꡬνμ ν¬ν¨ν ꡬ체νλ κ°μ²΄κ° μλ μΆμνλ κ°μ²΄λ‘ μνΈμμ©ν μ μμ
- μλ°μ μΈν°νμ΄μ€ κ°λ
κ³Ό κ°μ → λ©μλ κΈ°λ° μΈν°νμ΄μ€
- μΈν°νμ΄μ€λ λ€νμ±μ ꡬννκΈ° μν λꡬ
type Logger interface {
Log(msg string)
}
type FileLogger struct{}
func (f FileLogger) Log(msg string) {
fmt.Println("[File]", msg)
}
type ConsoleLogger struct{}
func (c ConsoleLogger) Log(msg string) {
fmt.Println("[Console]", msg)
}
func Process(logger Logger) {
logger.Log("μ²λ¦¬ μμ")
// ...
logger.Log("μ²λ¦¬ μ’
λ£")
}
func main() {
fileLogger := FileLogger{}
consoleLogger := ConsoleLogger{}
Process(fileLogger)
Process(consoleLogger)
}
β μμ‘΄μ± μ£Όμ
(DI)
μλΉμ€ κ³μΈ΅μμ μμ‘΄μ± λΆλ¦¬
// μΈν°νμ΄μ€ μ μ
type UserRepository interface {
FindByID(id int) (*User, error)
}
// μ€μ ꡬν체
type MySQLUserRepository struct {
db *sql.DB
}
func (r *MySQLUserRepository) FindByID(id int) (*User, error) {
// DBμμ μ¬μ©μ μ‘°ν
...
}
// μλΉμ€ κ³μΈ΅
type UserService struct {
repo UserRepository // μΈν°νμ΄μ€μ μμ‘΄
}
func (s *UserService) GetUser(id int) (*User, error) {
return s.repo.FindByID(id)
}
// UserRepositoryμ λν Mockμ λ§λ€μ΄ λ¨μ ν
μ€νΈλ₯Ό μ½κ² μμ±ν μ μμ
// MySQL μΈμ Redis, Memory κΈ°λ° λ± λ€μν ꡬνμ²΄λ‘ κ΅μ²΄ κ°λ₯
β λΉ μΈν°νμ΄μ€ νμ©
λΉ μΈν°νμ΄μ€λ ν
νλ¦Ώ or μ λ€λ¦ μ²λΌ μ΄λ€ νμ
μ΄λ λ°μμ€ μ μλ νν
// JSON μμ
var result map[string]interface{}
err := json.Unmarshal([]byte(jsonStr), &result)
fmt.Println(result["price"]) // float64, string λ± λ€μν νμ
μΌ μ μμ
// 컨ν
μ΄λ μλ£κ΅¬μ‘° ꡬν
type Stack struct {
items []interface{}
}
func (s *Stack) Push(v interface{}) {
s.items = append(s.items, v)
}
func (s *Stack) Pop() interface{} {
if len(s.items) == 0 {
return nil
}
last := s.items[len(s.items)-1]
s.items = s.items[:len(s.items)-1]
return last
}
- μ£Όμμ¬ν
- νμ μμ μ± μμ(μλͺ»λ νμ → ν¨λ λ°μ κ°λ₯)
- λ¨μ© μν(λͺ¨λ κ±Έ interface{}λ‘ μ²λ¦¬νλ©΄ μ μ§λ³΄μ μ ν)
- λμ: μ λ€λ¦(Go 1.18 μ΄ν)
type Stack[T any] struct {
items []T
}
func (s *Stack[T]) Push(v T) {
s.items = append(s.items, v)
}
β any
- Go 1.18λΆν° λμ λ μ λ€λ¦ μ§μ νμ
- type any = interface{}
var x any
x = 123
fmt.Println(x)
x = "hello"
fmt.Println(x)
β νμ μ€μμΉ
var x any = "hello"
switch v := x.(type) {
case int:
fmt.Println("μ μ:", v)
case string:
fmt.Println("λ¬Έμμ΄:", v)
default:
fmt.Println("μ μ μλ νμ
")
}
β νΉν json μ§λ ¬νμ λ§μ΄ μ¬μ©
var data map[string]any
err := json.Unmarshal([]byte(jsonStr), &data)
β λ νμ΄ν
λ νμ΄ν(Duck Typing)μ “μ΄λ€ νμ
μ΄ νΉμ λ©μλλ₯Ό κ°μ§κ³ μλ€λ©΄, κ·Έ νμ
μ ν΄λΉ μΈν°νμ΄μ€λ₯Ό ꡬνν κ²μΌλ‘ κ°μ£Όνλ€”λ κ°λ
. Goμμλ λͺ
μμ μΌλ‘ implements κ°μ ν€μλλ₯Ό μ°μ§ μκ³ λ μ묡μ μΌλ‘ μΈν°νμ΄μ€λ₯Ό λ§μ‘±
package main
import "fmt"
// μΈν°νμ΄μ€ μ μ
type Walker interface {
Walk()
}
// νμ
μ μ
type Dog struct{}
func (d Dog) Walk() {
fmt.Println("Dog walks")
}
type Cat struct{}
func (c Cat) Walk() {
fmt.Println("Cat walks")
}
// μΈν°νμ΄μ€λ₯Ό μ¬μ©νλ ν¨μ
func StartWalking(w Walker) {
w.Walk()
}
func main() {
dog := Dog{}
cat := Cat{}
StartWalking(dog) // Dogλ λͺ
μμ μΌλ‘ Walkerλ₯Ό ꡬννμ§ μμμ§λ§ Walk() λ©μλκ° μμΌλ―λ‘ μ¬μ© κ°λ₯
StartWalking(cat) // Catλ λ§μ°¬κ°μ§
}
μλ¬ νΈλ€λ§
β κΈ°λ³Έ Go ν¨μλ μλ¬κ° λ°μν κ°λ₯μ±μ΄ μμΌλ©΄ λ³΄ν΅ λ€μκ³Ό κ°μ΄ error νμ μ ν¨κ» 리ν΄
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, fmt.Errorf("division by zero")
}
return a / b, nil
}
result, err := divide(10, 2)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Result:", result)
β Error() λ©μλλ₯Ό ꡬννλ©΄ μ΄λ€ νμ
μ΄λ errorλ‘ μ¬μ©ν μ μμ
type error interface {
Error() string
}
β fmt.Errorf: μλ¬ ν¬λ§· μμ±
err := fmt.Errorf("νμΌ μ΄κΈ° μ€ν¨: %v", err)
β μ¬μ©μ μ μ μλ¬ νμ
type MyError struct {
Code int
Msg string
}
func (e MyError) Error() string {
return fmt.Sprintf("Error %d: %s", e.Code, e.Msg)
}
return MyError{Code: 404, Msg: "Not Found"} // μ€λ¬΄ μ½λ κΈ°λ°(μμ£Ό μ¬μ©λ¨)
β λ‘κ·Έμ μλ¬ λΆλ¦¬ μλ¬λ₯Ό 리ν΄νλ ν¨μλ λ‘κ·Έλ₯Ό μ°μ§ μκ³ νΈμΆμκ° νλ¨νλλ‘ μμ: νΈμΆ μΈ‘μμ log.Println(err) λλ fmt.Println(err) μ²λ¦¬
func readFile(path string) ([]byte, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("readFile: %w", err)
}
return data, nil
}
β μ£Όμ νΉμ§
νλͺ© | μ€λͺ |
error μΈν°νμ΄μ€ | Error() string λ©μλλ§ κ΅¬ν |
fmt.Errorf | λ©μμ§ ν¬ν¨ μλ¬ μμ± (%wλ‘ κ°μΈκΈ° κ°λ₯) |
errors.Is/As | μλ¬ λΉκ΅ λ° λ€μ΄μΊμ€ν |
panic/recover | μΉλͺ μ μν© λλΉ (μΌλ° λ‘μ§μμ μ§μ) |
μ¬μ©μ μ μ μλ¬ νμ | μ€λ¬΄ μ½λμμ μμΈν μλ¬ μ λ¬ κ°λ₯ |
sentinel errors | κ³ μ λ μλ¬ κ°μΌλ‘ μν κ΅¬λΆ |
early return ν¨ν΄ | μ½λ κ°λ μ± ν보μ μ€μ |
'νλ‘κ·Έλλ° μΈμ΄ > Go & Rust' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[Go] Modern Go κΈ°λ³Έ (0) | 2025.05.21 |
---|---|
[Go] Golang κΈ°λ³Έ μκ°(νμ , λ³μ, ν¨μ, λ¬Έλ²) (1) | 2023.04.16 |
λκΈ