프로그래밍을 하다보면 수많은 함수를 만들게 되는데, 가끔식 객체나 값 자체에 만들어 둔 함수를 추가해서 항상 사용하고 싶을 때가 있습니다.
예전에 만들어진 C나 C++과 같은 프로그래밍 언어에서는 지원하지 않지만 비교적 최근에 만들어진 Kotlin이나 C# 등의 최신 언어들은 이를 확장 함수라는 이름으로 제공해줍니다.
Scala도 역시 유사하게 implicit class 라는 이름으로 이 기능을 제공해줍니다.
implicit class
Scala는 2.10 이전에도 implicit 함수라는 이름으로 이러한 기능을 제공해주었습니다.
이를 이용해 자체적인 라이브러리를 구현하고 외/내부 DSL을 지원해 줄 수 있어 편리하였지만 이를 한 군데 뭉쳐놓을 만한 곳이 존재하지 않아 상당히 귀찮기도 했습니다.
이러한 변환을 더 완벽히 지원해주기 위해 Scala는 2.10부터 implicit class 기능을 지원해주었습니다.
implicit class는 단순히 implicit 키워드가 클래스의 선언부 앞에 존재하는 클래스로, 컴파일러는 필요한 상황에 다른 타입에서 implicit class 타입으로 변환하는 생성자를 만들어내고 주입해줍니다.
사용자는 원하는 타입이 implicit class로 변환되었는지 아닌지 신경쓰지 않고 코드를 짤 수 있어 더욱 효율적으로 코드를 작성할 수 있게 되었습니다.
다만, 이러한 암시적 변환이 지속적으로 사용되면 어느 곳에서 암시적 변환이 일어나고 어느 곳에서 일어나지 않는지 사용자는 알기 어려우므로 각 팀의 상황에 알맞게 적절한 상황에서만 사용하는 것이 좋습니다.
implicit class의 선언
implicit class를 만들기로 했다면 다음의 규칙을 지켜서 만들면 됩니다.
- class 앞에 implicit 키워드를 붙인다
- (각 팀의 상황에 맞게 키워드를 정해서) implicit class의 이름을 짓습니다 (대부분 RichXXX로 지으면 알맞습니다)
- 변환을 원하는 타입을 하나만 생성자 파라미터로 받습니다
- class 내부에 필요한 변환 함수들을 작성합니다
예시는 다음과 같습니다.
implicit class RichInt(target: Int) {
def loop(func: => Unit): Unit = {
var count = 0
while (count < target) {
func
count += 1
}
}
}
위의 함수는 Int를 RichInt로 변환해주는 암시적 클래스이고, 내부에는 Int 숫자만큼 반복하는 반복 함수를 정의하였습니다.
이를 통해 for (comprehension이 아닙니다) 을 흉내내어 코드를 작성할 수 있습니다.
val num = 4
num.loop {
println("loop!")
}
/*
출력
loop!
loop!
loop!
loop!
*/
Scala의 implicit은 매우 유용한 기능이지만 남용하면 코드를 읽고 이해하기 어려우니 적절히 사용하는 것을 추천합니다.
프로그래밍을 하다보면 수많은 함수를 만들게 되는데, 가끔식 객체나 값 자체에 만들어 둔 함수를 추가해서 항상 사용하고 싶을 때가 있습니다.
예전에 만들어진 C나 C++과 같은 프로그래밍 언어에서는 지원하지 않지만 비교적 최근에 만들어진 Kotlin이나 C# 등의 최신 언어들은 이를 확장 함수라는 이름으로 제공해줍니다.
Scala도 역시 유사하게 implicit class 라는 이름으로 이 기능을 제공해줍니다.
implicit class
Scala는 2.10 이전에도 implicit 함수라는 이름으로 이러한 기능을 제공해주었습니다.
이를 이용해 자체적인 라이브러리를 구현하고 외/내부 DSL을 지원해 줄 수 있어 편리하였지만 이를 한 군데 뭉쳐놓을 만한 곳이 존재하지 않아 상당히 귀찮기도 했습니다.
이러한 변환을 더 완벽히 지원해주기 위해 Scala는 2.10부터 implicit class 기능을 지원해주었습니다.
implicit class는 단순히 implicit 키워드가 클래스의 선언부 앞에 존재하는 클래스로, 컴파일러는 필요한 상황에 다른 타입에서 implicit class 타입으로 변환하는 생성자를 만들어내고 주입해줍니다.
사용자는 원하는 타입이 implicit class로 변환되었는지 아닌지 신경쓰지 않고 코드를 짤 수 있어 더욱 효율적으로 코드를 작성할 수 있게 되었습니다.
다만, 이러한 암시적 변환이 지속적으로 사용되면 어느 곳에서 암시적 변환이 일어나고 어느 곳에서 일어나지 않는지 사용자는 알기 어려우므로 각 팀의 상황에 알맞게 적절한 상황에서만 사용하는 것이 좋습니다.
implicit class의 선언
implicit class를 만들기로 했다면 다음의 규칙을 지켜서 만들면 됩니다.
- class 앞에 implicit 키워드를 붙인다
- (각 팀의 상황에 맞게 키워드를 정해서) implicit class의 이름을 짓습니다 (대부분 RichXXX로 지으면 알맞습니다)
- 변환을 원하는 타입을 하나만 생성자 파라미터로 받습니다
- class 내부에 필요한 변환 함수들을 작성합니다
예시는 다음과 같습니다.
implicit class RichInt(target: Int) { def loop(func: => Unit): Unit = { var count = 0 while (count < target) { func count += 1 } } }
위의 함수는 Int를 RichInt로 변환해주는 암시적 클래스이고, 내부에는 Int 숫자만큼 반복하는 반복 함수를 정의하였습니다.
이를 통해 for (comprehension이 아닙니다) 을 흉내내어 코드를 작성할 수 있습니다.
val num = 4 num.loop { println("loop!") } /* 출력 loop! loop! loop! loop! */
Scala의 implicit은 매우 유용한 기능이지만 남용하면 코드를 읽고 이해하기 어려우니 적절히 사용하는 것을 추천합니다.