본문 바로가기
Golang/Study

chapter3(9) method - signature

by 윤원용 2022. 2. 11.

개인적으로 method랑 function은 구분해야 한다 생각하는데 책에 method라 나와있다. 그래서 그냥 method라 하겠다.

Go는 Java와 달리 method를 아무 곳에서든 선언하고 참조할 수 있다. (Java는 Class나 interface scope 하위에서만 선언이 가능함)

Java에서는 접근 제한자(access modifier), 반환 타입, 함수명, parameter(파라미터), 예외처리, 이런 순서로 선언한다.

java의 method 선언

하지만 오늘 주제는 signature이기 때문에 다 필요 없고 함수명과 parameter에 초점을 맞추면 된다. Go에서 함수를 선언하는 방법은 func 예약어로 시작하여 중괄호({})로 끝난다. 보통 중괄호를 scope(스코프)라고 말하니 이제부터 중괄호를 scope라 하겠다.

go의 method 선언

주의할 점은 C 계열 언어처럼 scope의 시작점과  func 예약어가 다른 줄에 위치하면 에러가 발생한다.

개인적 추측으로는 세미콜론(;)을 생략하게 만든 문법이 원인인 것 같다.

scope 시작 위치와 func 예약어의 위치가 다를 때 발생하는 에러

위와 같이 Go는 까탈스러운 몇 가지 문법들이 있어서 장단점이 극대화되는 것 같다. 눈치가 빠른 사람들은 이미 알겠지만 함수명을 보면 조금 특이한 부분이 있는데 다른 언어들은 주로 카멜 표기법(Camel Case)을 사용하는 반면 Go는 파스칼 표기법(Parscal Case)을 권장한다. 여기서 먼지 팁이 있는데 Go에서 지원하는 내장 api(import 없이 쓸 수 있는 함수들)는 ParscalCase가 아니다. ㅋㅋ parameter는 함수명 뒤에 오는 소괄호(( )) 안에 명시할 수 있는데 Go는 Java와 달리  

변수의 타입이 같으면 변수 타입을 한 번만 명시해도 된다. Java와 비교해보면

public void myMethod(int i, int j) {
}

이렇듯 parameter list에 똑같은 int형 parameter를 두 개 받을 때 int를 두 번 써줘야 한다. 반면 Go는

func MyFunction(i, j int) {
}

위 코드와 같이 변수명을 콤마(,)로 구분한 뒤 마지막에 타입을 명시하면 끝이다.

 

사실 method signature를 이야기하면 overloading(오버 로딩)은 당연하듯 뒤 따라오는 주제이다. overloading을 간단히 설명하면 함수명이 같고 parameter list의 형태를 다르게 만드는 것을 뜻한다. Go를 공부하면서 엄청 놀랍게 느껴지는 몇 가지들이 있었는데 함수 부분에서도 있다. 그것은 바로 overloading을 지원 안 한다는 것이다.

overloading

조금 찾아보니 interface{} 타입을 사용하여 overload를 비슷하게 구현할 수 있지만 parameter의 타입을 검증하는 비용이 발생한다고 한다. (지원 안 하는 이유는 함수의 일관성 때문이라고 찾아볼 때 봤다.)

parameter list에 parameter가 같은 타입이면서 동적으로 받아야 할 때는 varargs [variable arguments](...)를 이용할 수 있다. 문법은 Java랑 Go랑 같은데 거의 모든 언어에서 ... 를 사용하면 varargs를 뜻하는 것 같다.(Javascript도 똑같음)

Java든 Go든 argument는 parameter의 타입형 배열로 접근할 수 있다. Go에서 parameter i의 argument를 출력해보면

go varargs

위와 같이 출력된다. Go는 특별한 문법이 있는데 바로 parameter를 생략할 수 있다. _(underbar)를 사용하면 되는데

parameter 무시하기

위 사진과 같다. 내 생각에는 paramter 무시가 아니고 argument 무시인 거 같은데 책에는 paramter 무시라고 나와있다. 그 이유는 method signature에 맞게 호출해야 하는데 paramter를 무시한다는 건 argument를 한 개만 넣어도 호출할 수 있어야 하지 않을까???

parameter 무시 예제

위처럼 에러가 발생한다. 그럼 method signature에 맞게 호출해야 하는 건데... 왜! paramter 무시라 했을까 의문이다.

책에선 나의 궁금증을 해소할 답은 없지만 사용 처를 말해주고 있다. overloading이 없는 Go에서 함수를 정의하면 수정하기가 어렵다. 예를 들어 parameter 두 개를 받는 함수를 많은 파일들에서 사용하고 있을 때 함수의 paramter list를 수정할 때를 예로 들고 있다. 해당 함수를 호출하는 다른 파일들을 전부 수정할 필요 없이 _(under bar)를 이용하여 해결할 수 있다고 하는데 개인적으로는 좋은 해결 방안인지 모르겠다... 더 헷갈릴 거 같은데...?

 

다음은 method의 반환을 포스트 하겠다.

그럼 ㅃ2~~~