Search

[Go 기초] [#7] 함수

요약
함수의 종류와 선언 방법 및 사용 방법
썸네일
https://noticon-static.tammolo.com/dgggcrkxq/image/upload/v1566913552/noticon/xjarxsfmmcouhih40val.png
작성일자
2024/04/15 11:26
수정일자
2024/05/18 07:43
스택
Go
카테고리
기초
태그
함수
클로저
익명함수

함수

함수란 특정 작업을 수행하는 묶음 코드입니다. 반복되는 코드들을 함수로 묶어서 관리한다면 코드의 재사용성을 높일 수 있고, 가독성 또한 좋아집니다.
Go에서 함수를 선언하기 위해서는 func 키워드를 사용합니다.
예를 들어, 두 개의 정수를 더하는 함수는 다음과 같이 선언할 수 있습니다.
package main import "fmt" // add 함수 func add(x int, y int) int { return x + y } func main() { a := 1 b := 2 fmt.Printf("두 수의 합: %d\n", add(a, b)) } // 실행 결과 // 두 수의 합: 3
Go
복사
Go 언어에서 사용할 수 있는 함수는 다음과 같은 특징이 존재합니다.

Convention

Go 언어에서 전역 변수나 함수를 선언할 때는 다음과 같은 명명 규칙이 존재합니다.
대문자로 시작하는 전역 변수, 구조체의 멤버 변수, 함수는 외부 패키지에서 접근하거나 호출할 수 있습니다. (Java Public 선언과 유사한 효과)
반면, 소문자로 시작하는 전역 변수, 구조체의 멤버 변수, 함수는 외부 패키지에서 접근하거나 호출할 수 없습니다. (Java Private 선언과 유사한 효과)
이에 대한 자세한 내용은 패키지 부분에서 다루겠습니다.

Call By Value

Go 언어에서는 기본적으로 Call By Value 방식을 사용합니다.
이는 함수에 값이 전달될 때, 실제 값이 복사되어 전달되는 방식입니다. 따라서, 함수 내에서 매개변수의 값을 변경해도 함수 밖의 원본 값은 변하지 않습니다.
package main import "fmt" func callByValue(x int) { // 매개변수의 값을 변경해도 원본 값에는 영향을 주지 않습니다. x = 10 } func main() { value := 5 fmt.Printf("Call By Value 호출 전: %d\n", value) callByValue(value) fmt.Printf("Call By Value 호출 후: %d\n", value) } // 실행 결과 // Call By Value 호출 전: 5 // Call By Value 호출 후: 5
Go
복사

Call By Reference

Call By Reference 방식은 매개변수로 전달된 값의 주소값을 사용하여 원본 데이터에 접근하고 수정하는 방식입니다.
Go에서는 이를 위해 포인터를 사용합니다. 따라서, 함수 내에서 매개변수의 값을 변경하면 함수 밖의 원본 값도 함께 변경됩니다.
package main import "fmt" func callByReference(x *int) { // 포인터를 통해 원본 값을 변경할 수 있습니다. *x = 10 } func main() { reference := 5 fmt.Printf("Call By Reference 호출 전: %d\n", reference) callByReference(&reference) fmt.Printf("Call By Reference 호출 후: %d\n", reference) } // 실행 결과 // Call By Reference 호출 전: 5 // Call By Reference 호출 후: 10
Go
복사

가변 인자 함수 (Variadic Function)

가변 인자 함수는 매개변수의 수가 고정되지 않고, 다양한 수의 인자를 받을 수 있는 함수를 말합니다.
Go에서는 매개변수 이름 뒤에 ... 을 붙여서 가변 인자 함수를 선언할 수 있습니다.
package main import "fmt" // 가변 인자 함수는 이렇게 선언합니다. func sum(nums ...int) int { total := 0 for _, num := range nums { total += num } return total } func main() { // sum 함수는 가변 인자를 가지는 함수이기 때문에 // 이처럼 전달하는 매개 변수의 개수를 유동적으로 변경할 수 있습니다. fmt.Printf("가변 인자 함수 호출 결과 1: %d\n", sum(1, 2, 3)) fmt.Printf("가변 인자 함수 호출 결과 2: %d\n", sum(1, 2, 3, 4, 5)) } // 실행 결과 // 출력: 가변 인자 함수 호출 결과 1: 6 // 출력: 가변 인자 함수 호출 결과 2: 15
Go
복사

함수 반환값

Go의 함수는 하나 이상의 반환값을 가질 수 있습니다.
반환값이 여러 개일 경우, 괄호 '(' ')'로 묶어서 표현합니다.
또한, Go는 반환값에 이름을 붙여 사용할 수 있어, 반환값이 어떤 의미를 가지는지를 명확하게 표현할 수 있습니다.
package main import "fmt" // divide 함수는 int, int, error 3개의 값을 동시에 반환하는 함수입니다. func divide(dividend, divisor int) (int, int, error) { if divisor == 0 { return 0, 0, fmt.Errorf("0으로 나눌 수 없습니다") } quotient := dividend / divisor remainder := dividend % divisor return quotient, remainder, nil } func main() { // Go 에서는 이처럼 여러개의 반환값을 가지는 함수를 만들고 사용할 수 있습니다. q, r, err := divide(10, 3) if err != nil { fmt.Printf("에러 발생: %v\n", err) } else { fmt.Printf("나눗셈 결과: 몫(%d)/나머지(%d)\n", q, r) } } // 실행 결과 // 나눗셈 결과: 몫(3)/나머지(1)
Go
복사

익명 함수

익명 함수는 이름 없이 선언되는 함수입니다.
익명 함수는 곧바로 실행될 수 있으며, 변수에 할당하거나 다른 함수의 인자로 전달할 수도 있습니다.
package main import "fmt" func main() { // 익명 함수는 이렇게 선언 하고 즉시 호출할 수 있습니다. func() { fmt.Println("이것은 익명 함수입니다.") }() // 익명 함수는 변수에도 할당하여 사용할 수 있습니다. anonymousFunc := func() { fmt.Println("익명 함수는 이렇게 변수에 할당할 수 있습니다.") } anonymousFunc() } // 실행 결과 // 이것은 익명 함수입니다. // 익명 함수는 이렇게 변수에 할당할 수 있습니다.
Go
복사

클로저 (Closure)

클로저는 함수 바깥에 있는 변수를 참조하는 함수를 일컫습니다.
클로저와 익명 함수를 적절히 사용한다면 복잡하게 전달되어야 할 매개변수를 간소화하고 코드를 좀 더 간단하게 만들 수 있습니다.
package main import "fmt" // 클로저 함수 func outer() func() int { i := 0 return func() int { i++ return i } } func main() { counter := outer() fmt.Println("클로저 카운트:", counter()) fmt.Println("클로저 카운트:", counter()) } // 실행 결과 // 클로저 카운트: 1 // 클로저 카운트: 2
Go
복사

끝마치며

함수는 반복되는 코드들을 묶어 재사용하므로써 소스 코드의 품질을 높일 수 있는 가장 기본적인 방법 중 하나입니다.
Go 언어 프로그래밍을 할 때, 반복적으로 해야하는 일들을 복사 붙여넣기 하기 보다는 함수를 적극적으로 사용하여 반복을 줄이고 재사용할 수 있도록 연습해보세요.
강의 목록

참조