상세 컨텐츠

본문 제목

7장 함수

Programming/Go입문

by 크리두 2021. 5. 16. 22:15

본문

반응형

7.1 함수 정의

함수 구성은 함수 키워드, 함수명, 매개변수, 반환타입, 함수 코드 블록으로 구성이 된다. 다른 언어와는 달리 go 언어는 함수 정의를 호출보다 먼저하지 않는, 순서와 상관없이 가능하다.

function

  • 함수 정의 키워드 : func이라는 키워드를 사용해 함수 정의를 알림
  • 함수명 : 함수명의 명명 규칙은 변수명과 같음
  • 매개 변수 : 소괄호 안에 매개변수를 넣음
  • 반환타입 : 반환하는 값이 있으면 적고, 아니면 비움
  • 함수 코드 블록 : 중괄호로 코드 블록을 표시함

Go 언어는 특이한 점이 함수 코드 블록 시작인 중괄호가 정의하는 라인과 같아야 한다.

package main

import "fmt"

func Add(a int, b int) int { // ❶
    return a + b // ❷
}

func main() {
    c := Add(3, 6) // ❸
    fmt.Println(c) // ➍
}
9

Add라는 함수를 정의한다 ❶. 두 정수 타입 매개변수 a와 b를 입력 받아 ❷ 그 둘의 합을 반환한다. Add() 함수를 호출한다 ❸. 반환값을 c에 저장한다. c를 출력한다 ➍.

7.2 함수를 호출하면 생기는 일

다른 언어도 마찬가지 이지만 함수 호출 시 입력하는 값을 인수, 바로 아규먼트(argument)라고 한다. 반대로 함수가 외부로부터 입력받는 변수를 매개 변수 또는 파라미터(parameter)라고 부른다.

함수를 호출하면 입력한 값은 그대로 사용되는 것이 아니라 값을 복사해 사용하게 된다. 다음 예제에서 Add()라는 함수를 호출할 때 인수가 매개변수에 복사되어 전달되는 과정을 보여준다.

c:= Add(3,6) // ❶ 함수 호출

func Add(a inst, b int) int { // ❷ 매개변수 생성 및 초기화
  // a와 bfmf 더한 결과를 반환
  return a + b // ❸ 값 반환(복사), ➍ a + b 값을 복사해서 c로 반환
} // ➎ 로컬 변수 삭제

❶ Add() 함수 호출 한다.

❷ 매개 변수를 선언하고 입력한 인수값을 복사한다. 위 예제에서는 3과 6이 a와 b에 복사된다.

❸ return 키워드를 사용해서 함수 결과를 반환한다.

➍ 반환된 값은 함수가 호출된 곳을 대체하는 것과 같다. ➍ -> ❶로 값을 복사해서 c로 반환

➎ 호출한 함수가 종료되면 함수에서 사용한 지역 변수에 접근할 수 없다.

c:= Add (3,6)
c:= 9 ➏ 대입 연산

➏ c에 반환값이 대입(복사)된다.

7.3 함수는 왜 쓰는가?

함수를 사용하게 되면 반복 사용되는 코드를 묶어서 중복 코드를 제거하여 재사용이 가능하게 만든다.

함수를 사용하여 반복되는 부분을 호출해서 사용해서 반복 작업을 가능하게 하였으나 문제가 생긴다. 같은 작업을 사용하기 위해 호출을 했지만 약간 다른 작업이 필요하는 경우가 생긴다. 이 문제는 데이터를 사용하여 저장을 하고 돌아가는 위치도 저장된 값을 이용하여 돌아가는 식으로 해결을 한다.

그런데 또 문제가 발생한다. 값이 하나가 아니라 2개 이상이 바뀌는 경우가 생긴다. 메모리에 저장해 놓을 값이 많아졌다 적어졌다 하기 때문에 필요한 값을 연속으로 저장을 한다. 그리고 호출을 할 때 끝에 저장해 놓은 값부터 사용한 다음, 다 읽었으면 저장한 값을 비운다.

이러한 과정들을 통틀어 함수콜이라고 한다. 돌아갈 위치, 필요한 값을 적고 함수의 위치로 점프를 하여 실행한다. 함수는 저장된 맨 뒤 값을 읽어오면서 저장된 값을 삭제하면서 실행한다 (FILO : 선입 후출 구조 자료형). 그 다음 돌아갈 위치 값을 읽어 다시 원래 위치로 돌아온다.

7.3.1 멀티 반환 함수

함수는 여러 개의 값을 반환 할 수 있다. 반환하는 값이 여러 개일 때는 소괄호로 묶어서 표현한다.

package main

import "fmt"

func Divide(a, b int) (int, bool) { // ❶ 함수 선언
    if b == 0 {
        return 0, false // ❷ 제수가 0일 때 반환
    }
    return a / b, true // ❸ 제수가 0이 아닐 때 반환
}

func main() {
    c, success := Divide(9, 3) // ➍ 제수가 0이 아닌 경우
    fmt.Println(c, success)
    d, success := Divide(9, 0) // ➎ 제수가 0인 경우
    fmt.Println(d, success)
}
3 true
0 false

❶ Divide( ) 함수를 정의한다. int 타입 a,b를 매개변수로 받고 int 타입과 bool 타입을 반환 (멀티 반환)

❷ 나눗셈 제수가 0이면 0과 false를 반환

❸ 제수가 0이 아닐 때는 나눗셈 결과와 true를 반환

➍➎ Divide( ) 함수를 호출하고, 그 결과를 변수 c와 success로 받는다. 첫 번째 반환값은 c, 두 번째 반환값은 success에 대입된다.

리턴값을 받을 때는 c, success :=처럼 변수를 콤마로 구분하여 여러 개 지정한다. 리턴 값은 함수가 지정한 순서대로 반환이 된다. 따라서 리턴값을 반환할 변수 하나만 지정하는 경우 하나만 받게 된다.

첫 번째 리턴값은 생략하고 두 번째 리턴값부터 사용하고 싶다면 _ (밑줄 문자)를 사용해서 생략하여 사용할 수 있다.

7.3.2 변수명을 지정해 반환하기

반화 타입을 적을 때 변수명까지 지정하면, return 문으로 해당 변수를 명시적으로 변화하지 않아도 값을 반환이 가능한다.

package main

import "fmt"

func Divide(a, b int) (result int, success bool) { // ❶ 반환할 변수명이 명시된 함수 선언부
    if b == 0 {
        result = 0
        success = false
        return // ❷ 명시적으로 반환할 값을 지정하지 않은 return문
    }
    result = a / b
    success = true
    return
}

func main() {
    c, success := Divide(9, 3)
    fmt.Println(c, success)
    d, success := Divide(9, 0)
    fmt.Println(d, success)
}
3 true
0 false

❶ 함수 선언부이다. 첫 번째 반환할 변수로 result, 두 번째는 success로 지정했다. 이렇게 지정한 result, success는 함수 내부에서 변수로 동작

❷ 함수 결과를 반활할 때 명시적으로 result, success를 지정하지 않아도 두 값이 반환된다.

반활할 변수에 이름을 지정할 경우 모든 반환 변수에 이름을 모두 지정하거나, 모두 지정하지 않아야 한다.

7.4 재귀 호출

재귀 호출(recursive call)은 함수 안에서 자기 자신 함수를 다시 호출하는 것이다.

아래 예제는 3부터 1까지 재귀 호출을 이용해서 출력하는 예제이다.

package main

import "fmt"

func printNo(n int) {
    if n == 0 { // ❶ 재귀 호출 탈출 조건
        return
    }
    fmt.Println(n)
    printNo(n - 1)          // ❷ 재귀 호출
    fmt.Println("After", n) // ❸ 재귀 호출 이후 출력
}

func main() {
    printNo(3) // ❹ 함수 호출
}
3
2
1
After 1
After 2
After 3

➍ printNo ( ) 함수를 호출한다.

❶ 탈출 조건(n이 0이 아니면)인지 확인한다.

❷ printNo ( ) 함수를 다시 호출한다. 호출 순서는 printNo(3) -> printNo(2) -> printNo(1) -> printNo(0) 순으로 호출된다.

❸ printNo(0)일 때 탈출 조건이 되어 함수가 종료되면 호출자인 printNo ( ) 위치로 반환되고 거기에서 "After" 메시지가 출력된다.

 

Ref. Tucker의 Go 언어 프로그래밍 - 공봉식
『Tucker의 Go 언어 프로그래밍』 스터디 요약

반응형

'Programming > Go입문' 카테고리의 다른 글

6장 연산자  (0) 2021.05.12

관련글 더보기

댓글 영역