본문 바로가기
320x100
320x100

코틀린에서 람다식을 사용할때 인자가 하나인 경우에 it으로 사용할 수 있다

 

2024년 11월 19일 기준 코틀린 최신버전인 2.021문서를 살펴보면 위의 내용이 나와있다

it

it: implicit name of a single parameter

-> 번역: 단일 매개변수의 암시적 이름

 

it의 활용 예시를 들기 위해.. 간단한 코드를 만들어봤다

* 간단한 포스팅용 코드이므로, Assertion이 없다고 불편해하지 마시라!ㅠ. 학습용 테스트도 테스트의 일부일 수 있는것처럼

it

package boki

import org.junit.jupiter.api.Test

class ItTest {
    data class Person(
        val name: String,
        val age: Int,
    )

    @Test
    fun test() {
        val people = listOf(
            Person(name = "Kim", age = 10),
            Person(name = "Lee", age = 20),
            Person(name = "Park", age = 30),
            Person(name = "Yong", age = 40),
        )
        println(people.filter { p: Person -> p.age in 10 until 30 }) // 명시적 타입 사용
        println(people.filter { p -> p.age in 10 until 30 }) // 컴파일러 타입 추론
        println(people.filter { it.age in 10 until 30 }) // 단일매개변수 람다식 it 키워드 사용
    }
}

 

실행결과는 뭐 뻔하지만... 요렇다

실행결과

코틀린에서 람다를 사용할때 단일 매개변수를 갖는 경우 it을 키워드로 쓸 수 있고, 영어를 읽듯 이것/그것으로 자연스레 해석된다

호불호가 있겠지만, 간단한 코드라면 it을 쓰는 것을 개인적으로는 선호한다

 

Q. 그렇다면 코틀린에서는 이 it을 어떻게 키워드로 사용할 수 있는걸까?

찾았다

뭔가 컴파일러 내부에 있을 것 같아서, 사용중인 코틀린 프로젝트의 library에서 compiler 관련 파일들을 살펴봤다

코틀린은 jetbrains에서 만들었기 때문에 root 패키지를 보면 org.jetbrains인 것을 볼 수 있다

하위에 kotlin/builtins 패키지를 살펴봤다. 참고로 빌트인 냉장고 이런거 들어봤을 것 이다. 그런 뜻의 built-in이다. 패키지명에 -를 사용할 수 없기때문에 요렇게 쓴 것 같다

어쨌든, 여기에서 StandardNames라는 object를 살펴봤는데, 내부에 IMPLICIT_LAMBDA_PARAMETER_NAME 키워드를 찾아볼 수 있었다

@field:kotlin.jvm.JvmField 
public final val IMPLICIT_LAMBDA_PARAMETER_NAME: org.jetbrains.kotlin.name.Name 
/* compiled code */

혹시나 바로 모르시는 분이 계실까봐! /* compiled code */는 무엇이냐하면

현재 kotlin-compiler-embeddable-1.9.25.jar라는 바이너리 파일에서 바이트코드를 IntelliJ가 디컴파일해서 보여준 상태인 것이다

 

그럼 이번에는 Kotlin Bytecode 툴을 이용해서 해당 파일을 또 디컴파일을 해보자

Kotlin Bytecode

var10000 = Name.identifier("it");
Intrinsics.checkNotNullExpressionValue(var10000, "identifier(...)");
IMPLICIT_LAMBDA_PARAMETER_NAME = var10000;

좀 더 정교한, 기존의 java코드에 가까운 로우레벨 코드를 얻을 수 있었다

내가 맞다면 인텔리제이 자체에서 제공해주는 디컴파일 1번, Kotlin Bytecode 툴을 통한 디컴파일 1번 총 2번의 디컴파일 과정을 거친 것이다

이 코드에서 Name.identifier("it"); 이라는 키워드를 찾을 수 있었다

 

이것으로는 좀 더 부족하다고 느껴서 원본코드를 보기 위해 Kotlin Github에 들어가보기로 했다

it

찾았다 이 친구..! 이게 원본 소스구만

kotlin/core/compiler.common/src/org/jetbrains/kotlin/bulitins/StandardNames.kt에 있었다

Ref

사용처를 찾아보니 총 5군데서 사용하고 있었다(현재파일 제외)

internal class KaFe10DescValueParameterSymbol
class FunctionDescriptorResolver
class FirCallCompleter
internal val DeclarationDescriptor.kaSymbolLocation: KaSymbolLocation
open class FirDeclarationsResolveTransformer

 

각각 책임과 역할이 잘 나뉘어 있을거라 생각한다

이동의 흔적들

나는 모두 들어가서 해당 usage를 살펴봤는데, 두번째 FunctionDescriptorResolver 클래스의 createValueParameterDescriptors의 메서드에서 it 파라미터를 생성하는 로직을 담당하는 것을 찾았다!

it 키워드 생성 로직

  • 조건체크:  if (expectedValueParameters.size == 1 && function is KtFunctionLiteral && function.getValueParameterList() == null)
  • true -> ValueParameterDescriptorImpl을 생성하며 파라미터이름으로 StandardNames.IMPLICIT_LAMBDA_PARAMETER_NAME을 지정
  • 마지막으로 추적 레코드에 BindingContext.AUTO_CREATED_IT를 기록하여, 생성된 파라미터가 it임을 명시적으로 추적 

 

결론

추가 정보

A.

Kotlin에서 람다 함수의 암시적 파라미터 이름으로 it을 사용할 수 있고, 이 it은 사용자가 명시적으로 파라미터를 선언하지 않을 때 기본으로 할당됨

이 이름은 Kotlin 컴파일러 내부에서 StandardNames.IMPLICIT_LAMBDA_PARAMETER_NAME으로 정의됨

이후 컴파일러 내부의 동작을 보면 FunctionDescriptorResolver의 createValueParameterDescriptors 메서드는 파라미터를 확인하며 파라미터가 단 하나이고, 사용자가 변수명을 지정하지 않은 경우를 체크해 해당 파라미터에 it이라는 이름을 부여하는 역할을 수행한다

it은 바이트코드 수준에서 ValueParameterDescriptor로 표현되며 Kotlin 코드에서 it을 참조하면 컴파일러는 바이트코드에 기록된 ValueParameterDescriptor 정보를 기반으로 이를 해석하여 동작

 

 

코틀린에서 어떻게 it을 변수로 사용하게 만드는지에 대해 단순히 사용하는 것을 넘어 조금 깊게 들어가서 알아봤다

12시부터 새벽4시 40분...까지 걸린 대략 4시간 반 정도의 여정이었다

 

 

다음에는 inline, invoke 등등.. 재밌는 것들에 대해서 또 딥하게 들어가봐야겠다

Under the Sea~~~ 🌊

 

 

 

 

- 출처

https://kotlinlang.org/docs/lambdas.html#it-implicit-name-of-a-single-parameter

 

Higher-order functions and lambdas | Kotlin

 

kotlinlang.org

https://github.com/JetBrains/kotlin/blob/3e8cf24ebe5a8b7639d2d6fc23d6bbe1db2f9ecd/core/compiler.common/src/org/jetbrains/kotlin/builtins/StandardNames.kt#L45

 

kotlin/core/compiler.common/src/org/jetbrains/kotlin/builtins/StandardNames.kt at 3e8cf24ebe5a8b7639d2d6fc23d6bbe1db2f9ecd · Je

The Kotlin Programming Language. . Contribute to JetBrains/kotlin development by creating an account on GitHub.

github.com

 

320x100

댓글