새소식

인기 검색어

개발일기

Kotlin에서 멤버 확장 함수는 왜 외부 파일에서 호출이 안되는 걸까?

  • -

최근 Kotlin을 사용하면서 TestStep을 선언할 때 확장 함수를 적극적으로 활용하고 만족하고 있다.

 

createMember, expectCommonMemberResponse, toResponse 등 함수들이 모두 확장 함수이다.

 

그러다가, 확장 함수를 멤버 함수로 선언할 수 있지만 그 경우 외부 파일에서 호출할 수 없기에 궁금증이 생겨 몇가지 실험을 해보았다.

 

우선 확장 함수를 최상단에 선언했을 때의 경우이다.

 

코틀린 코드

 

디컴파일한 코틀린 코드

디컴파일한 코드를 보면 최상위에 파일명에 해당하는 클래스를 선언하고, 그 안에 정적 메서드를 선언한 것을 볼 수 있다.

 

그에 반해, 멤버 함수로 확장 함수를 선언할 경우 다음과 같게 된다.

 

 

정적 메서드가 아닌 인스턴스 메서드가 된다.

 

Kotlin in Action을 보면 이런 말이 나온다.

JVM이 클래스 안에 들어있는 코드만을 실행할 수 있기 때문에 컴파일러는 이 파일을 컴파일할 때 새로운 클래스를 정의해준다. ... 코틀린 파일의 모든 최상위 함수는 이 클래스의 정적인 메서드가 된다.

 

즉, 최상위 함수일 때는 정적 영역으로 처리하게끔 만들고 멤버로 선언하면 인스턴스 메서드 처럼 동작하게 만들어주겠다는 의미같다.

 

 

따라서 인스턴스 확장 함수의 경우, 멤버 식별자에도 접근이 가능함을 확인할 수 있다.

 

또한, 다른 파일에서도 인스턴스로 접근하면 확장 함수에 접근할 수 있긴 하다. 심지어 private 식별자에도 접근할 수 있다.

 

 

확장 함수란, 첫 번째 인자를 this로 받은 것과 본질적으로 같기 때문이다.

 

그럼 여기서 궁금증이 든다. 멤버 함수도 정적 함수로 만들면 되는 것 아닌가? 왜 인스턴스 영역으로 보낸 것일까?

 

이건 내 생각인데, kotlin 측에서는 scope에 의해 침범할 수 있는 영역을 나눠준 것이 아닌가 싶다. 최상위 영역으로 보냈다는 것은 모든 곳에서 사용하고 싶지만 멤버로 선언했다는 것은 어디까지나 그 클래스에 종속되게 무언가를 처리하고 싶다는 의미에서 그런 것이 아닌가 싶다.

 

뭔가 삽질은 많이 했는데, 막상 내용을 정리해 보니 별 것 아닌 내용 같아 허탈하긴 하다. 그래도 이번 계기로 느낀 점이 있다면, 코틀린을 공부하더라도 자바를 꼭 병행해서 공부해야겠다는 점이다.

 

코틀린을 사용하다가 문제를 생기면 내부를 봐야하는데, 그 내부를 잘 알려면 결국 자바를 잘 알아야지 알 수 있다는 걸 느꼈다.

 

그리고 그냥 쌩 자바로만 코딩할 땐 못 느꼈던 자바의 포인트들을 오히려 코틀린을 사용하면서 알게 된 부분들도 있어 신선한 부분도 있었다.

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.