본문 바로가기

golang

golang4 함수

함수

golang의 함수는 다음과 같이 작성된다.

func add(a int32, b int32) int32 {
	return a + b
}

func 함수명(파라미터명 타입) 반환형

golang은 함수의 파라미터를 call by value와 cal by ref 를 모두 지원해준다. 이용하는 방식은 c언어와 비슷하다.

위의 add함수가 call by value방식으로 a와 b 파라미터를 입력받는 과정을 수행한다. call by ref는 다음과 같다.

func callByRef(num *int){
	*num=100
	fmt.Println("CallByRef Function is ",*num)
}

call by ref는 주소를 참조하는 방식이므로 포인터 연산자를 이용해서 call by ref를 수행한다. 단 call by ref는 인자값이 주소값이어야 하므로 함수를 호출할때 파라미터에 주소연산자를 표기하여야 한다.

다음의 코드를 보자

package main

import "fmt"

func main() {
	var num = 5
	fmt.Println("origin: ", num)
	callByValue(num)
	fmt.Println("call by value ", num)
	callByRef(&num)
	fmt.Println("call by reference ", num)
}

func callByValue(num int) {
	num = 10
	fmt.Println("CallByValue Function is ", num)
}

func callByRef(num *int) {
	*num = 100
	fmt.Println("CallByRef Function is ", *num)
}

실행결과는 다음과 같다.

golang


가변인자

golang의 가변인자는 다음과 같은 특징을 가진다.

  1. 가변인자로 전달된 값은 슬라이스 형태로 전달된다.
  2. 오직 1개의 타입으로만 가변인자로 받는다.
  3. 가변인자를 전달타입으로 명시했을 경우 슬라이스 전체를 가변인자로 삽입할 수 있다. 단 슬라이스가 call by reference형식으로 삽입된다.
package main

import "fmt"

func main() {
	var slice = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	// 1. 가변인자 방식
	variableFunction(1, 2, 3, 4, 5)
	// 2. slice를 인자로
	fmt.Println(`main func: `, slice)
	variableFunction(slice...)
	fmt.Println(`main func: `, slice)
}

func variableFunction(num ...int) {
	fmt.Println(`func: `, num)
	num[3] = 100
}

위의 코드의 실행결과는 다음과 같다.

golang

slice경우 variableFunction에서 slice값을 수정하면 메인 함수에서의 slice값도 수정된 것을 확인할 수 있다. 이를 통해 slice는 값 전체가 복사되는 것이 아닌 slice주소값만 넘겨주는 call by ref형식으로 동작함을 알 수 있다.


다중 리턴

golang은 함수가 여러개의 값을 리턴시킬 수 있다. 사용 방식은 다음과 같다.

package main

import "fmt"

func main() {
	const (
		num1 = 200
		num2 = 100
	)
	add, minus := multiReturn(num1, num2)
	fmt.Println(add, minus)
}

func multiReturn(num1, num2 int) (int, int) {
	var resultAdd = num1 + num2
	var resultMinus = num1 - num2
	return resultAdd, resultMinus
}

함수의 반환타입을 작성하는 부분에 소괄호에 반환시킬 타입을 작성시킨다. 작성한 타입 순서대로 반환을 수행하여야 한다. 실행결과는 다음과 같다.

다중리턴

Named Return Parameter

반환되는 값에 이름을 붙여주는 방식이다. 이렇게 들으면 새로운 방법인 것 처럼 보이지만 기능은 매우 단순하다.

Named Return Parameter의 기능은 반환값이 될 변수들을 미리 선언하는 것이다. 변수를 미리 선언하고 선언된 변수 순서대로 반환을 수행한다. 즉 return 예약어 뒤에 인자를 붙일 필요가 없다.

반환 값이 될 변수들을 미리 선언하므로 동일한 이름의 변수와 상수를 생성할 수 없다.

Named Return Parameter의 작성 방식은 반환타입을 작성하는 부분에 함수 파라미터 처럼 이름 타입 형식으로 작성한다.

func multiReturn(num1, num2 int) (resultAdd int, resultMinus int) {
	resultAdd = num1 + num2
	resultMinus = num1 - num2
	return
}

return 예약어 뒤에 인자를 작성 없이 반환해준다. 작성할 필요가 없다는 의미이지 작성을 하지 말아야한다는 의미는 아니다. 위의 코드같은 경우는 반환타입이 둘다 정수형이므로 다음과 같이 작성하여도 동작한다.

func multiReturn(num1, num2 int) (resultAdd int, resultMinus int) {
	resultAdd = num1 + num2
	resultMinus = num1 - num2
	return resultMinus, resultAdd
}

위처럼 작성하면 함수 반환 결과는 resultMinus, resultAdd 순서로 반환된다. 이렇게 작성도 가능하다는 것이지 굳이 이런식으로 순서를 햇갈리게 작성할 필요는 없다.

Named Return Parameter이 적용된 함수를 호출하는 함수 측면에선 다른 다중리턴 방식처럼 동일하게 사용한다.

다음은 코드를 보자

package main

import "fmt"

func main() {
	const (
		num1 = 200
		num2 = 100
	)
	add, minus := multiReturn(num1, num2)
	fmt.Println(add, minus)
}

func multiReturn(num1, num2 int) (resultAdd int, resultMinus int) {
	resultAdd = num1 + num2
	resultMinus = num1 - num2
	return
}

Named Return Parameter로 multiReturn함수를 작성하였다. 코드의 실행결과는 다중타입의 코드와 실행결과가 동이하다.


익명함수

golang도 익명함수가 작성이 가능하다. 말 그대로 함수명이 없는 함수이다.

익명함수는 프로그램 측면에서 다음과 같은 이점을 가진다.

  1. 익명함수가 존재하는 함수가 실행할 때만 메모리에 적재되어 수행된다.
  2. 함수를 변수처럼 사용가능하다. 함수를 파라미터처럼 다른 함수에 사용될 수 있다.

다음의 코드와 실행결과를 보자

package main

import "fmt"

func main() {
	function := func(n1, n2 int) int { return n1 + n2 }
	const num1 = 100
	const num2 = 200
	var result = TM(function, num1, num2)
	fmt.Println("Result: ", result)
}

func TM(function func(n1, n2 int) int, num1 int, num2 int) int {
	return function(num1, num2)
}

실행결과

TM에서 입력받을 함수와 파라미터를 받고 대신 실행시켜주고 결과를 반환한다. function에 선언 및 초기화된 익명함수를 마치 변수처럼 TM 함수에 넘겨주고 실행시킬 수 있다.

위의 코드에서 type을 지정해서 다음과 같이 줄여서 사용할 수 있다.

package main

import "fmt"

type myFunc = func(n1, n2 int) int

func main() {
	var function myFunc = func(n1, n2 int) int { return n1 + n2 }
	const num1 = 100
	const num2 = 200
	var result = TM(function, num1, num2)
	fmt.Println("Result: ", result)
}

func TM(function myFunc, num1 int, num2 int) int {
	return function(num1, num2)
}

'golang' 카테고리의 다른 글

golang7 slice  (0) 2022.01.09
golang6 구조체  (0) 2021.12.26
golang5 조건문과 반복문  (0) 2021.12.25
golang3 변수와 상수  (0) 2021.12.23
golang1 연산자  (0) 2021.12.19