Go언어에서 함수는 "func 함수이름 (매개변수이름 매개변수형) 반환형"이 기본적인 형식이라고 배웠습니다. 여기서 눈여겨봐야 하는 부분은 바로 '함수이름', '매개변수', '반환형'입니다. 왜냐하면 각 부분의 사용법에 따라 함수의 기능과 역할이 달라지기 때문입니다. 그래서 함수 챕터는 각 부분을 주제로 나눴습니다. 이번 강의에서 다룰 내용은 '매개변수'입니다. 매개변수는 언어를 불문하고 개발자들이 개발을 하면서 많이 헷갈려하는 부분입니다. 왜냐하면 코드가 길어지고 많은 변수를 사용하다보면 변수가 전역변수인지 지역변수인지 헷갈리게 됩니다. 그래서 에러가 발생하면 그 이유가 매개변수 사용에서의 실수일 가능성이 높습니다. 변수의 사용이 헷갈리는 것은 변수의 개념이 헷갈린다는 뜻이고 결국 함수 활용을 제대로 할 수 없다는 것입니다. 따라서 함수의 매개변수 개념을 잘 숙지해야합니다.
Go언어에서 매개변수는 Pass by value, Pass by reference, 가변 인자에 대해 알면 됩니다. 가변 인자는 변수의 접근 범위 내용과 좀 다르지만 매개변수와 관련된 내용이기 때문에 이번 강의에서 다루겠습니다.
Pass by value
이전 강의에서 함수에 대한 기본적인 형식과 기능을 배우면서 함수를 호출하는 방법에 대해 배웠습니다. Pass by value는 인자의 값을 복사해서 전달하는 방식입니다. 따라서 복사한 값을 함수 안에서 어떠한 연산을 하더라도 원래 값은 변하지 않습니다. 함수를 호출할 때는 "함수이름(변수이름)"만 입력하면 됩니다.
아래 코드를 바로 실행해보세요.
Pass by value는 어렵지 않고 다른 언어에서도 동일하게 쓰이기 때문에 간단하게 하고 넘어가겠습니다.
Pass by reference
사실 Java에 익숙한 개발자들이라면 Pass by reference의 개념에 익숙할 것입니다. Java는 객체 지향 언어로서 기본형 데이터 이외에 클래스 변수들은 전부 pass by reference를 기초로 두고있습니다. 물론 pass by value를 쓰지 못 하는 것은 아닙니다. Go언어는 분명 객체 지향을 따른다고 했지만 형태와 용법을 보았다시피 C언어와 비슷한 모습을 보입니다. 우리가 지금 Pass by value와 Pass by reference를 구분해 배우는 것은 이러한 이유 때문입니다. 따라서 Go언어에서는 C/C++ 언어에서 핵심 개념인 '포인터'라는 개념을 지원합니다. 우리는 Go언어를 공부하는 것이기 때문에 다른 언어에 대한 설명은 Go언어의 이해를 돕기 위한 간략한 설명정도만 하겠습니다. 매개변수를 pass by reference로 사용하기 위해 포인터에 대한 개념과 C/C++ 언어에서 사용되는 포인터와의 차이점을 알아야합니다.
'&' : 주소, '*' : 직접참조만 알아두세요. C언어에서 쓰이는 포인터에는 좀 더 다양하고 복잡한 용법이 있습니다. 하지만 Go언어는 포인터의 핵심 개념만 사용하도록 제공합니다.
- C언어에서는 배열이름 자체가 배열의 첫번째 인덱스 요소의 주솟값인데 Go언어는 그런 것이 없습니다. 주솟값은 어떤 변수 앞에 &를 붙이는 것만 기억하면 됩니다.
- C언어에서는 "*(배열이름+인덱스)"는 "배열이름[인덱스]"와 같은 기능을 했는데 Go언어는 그런 것이 없습니다. 직접 참조를 원하면 포인터 변수 앞에 *를 붙이는 것만 기억하면 됩니다.
- 함수를 호출할 때는 주솟값 전달을 위해 "함수이름(&변수이름)"을 입력하고 함수에서 매개변수이름을 입력할 때는 값을 직접 찹조하기 위해 *을 매개변수형 앞에 붙입니다. 그리고 함수 안에서 매개변수앞에 모두 *를 붙여야합니다.
아래 코드를 바로 실행해보세요.
a
의 값을 printSqure
함수 안에서 참조함으로써 다른 함수에서 연산을했음에도 불구하고 원래 값이 바뀝니다. - n개의 동일한 형의 매개변수를 전달합니다.
- 전달된 변수들은 슬라이스 형태입니다. 변수를 다룰 때 슬라이스를 다루는 방법과 동일합니다.
- 함수를 선언은 "func 함수이름(매개변수이름 ...매개변수형) 반환형" 형식으로 합니다. '매개변수형' 앞에 '...'을 붙이면 됩니다.
- 매개변수로 슬라이스를 전달할 수 있습니다. 다른 컬렉션 형태는 불가능합니다. 슬라이스를 전달할 때는 슬라이스 이름 뒤에 ...를 붙여서 "함수이름(슬라이스이름...)" 형식으로 함수를 호출하면 됩니다.
아래 코드를 바로 실행해보세요.
위 코드는 기능은 다르지 않고 슬라이스의 접근 방법을 다르게 활용한
addOne
과 addTwo
가변 인자 함수를 보여줍니다.