[코틀린] 코틀린 표준라이브러리(also, let, with, apply 등)의 확장함수에 대해 질문드려요ㅛ

조회수 481회
inline fun <T, R> T.run(block: T.() -> R): R {
    return this.block()
}

책을 보면 run 확장함수가 이런식으로 정의되어있다고 나와잇는데요.

이것에 대한 설명이 아래와 같습니다

block 매개변수로 T.() -> R 형태의 함수를 받는데,run 확장함수를 호출하면 곧바로 this.block() 을 호출하여, run의 리시버를 block이 가리키는 함수에 전달한다.

즉, "Hello".run { println(this) } 와 같이 호출하면 run 확장함수는 다음과 같이 된다.

fun String.run(block: String.() -> Unit): Unit {
    // block = println(this)
    return this.block()
}

여기서 이해가 잘안되는것이.. 확장함수하면 블록내부에서 this를 사용해서 리시버의 멤버에 접근이 가능

하잖아요?

그런데 여기서 this.block하면.. String 타입의 block() 멤버함수를 호출한다는 뜻같은데..

제가 아는한은 String 클래스 내부에는block함수가 없는걸로 아는데..이게 어떻게 가능한건가요?

return 에서그냥 block()이 되어야하는것이 아닌지..

그리고 추가적인 질문이 blockString.() -> Unit이면String의 확장함수를 매개변수로 받아야하는것아닌가요?

println은 그냥 println그 자체인데.. 어떻게 이게 되는건가요

많이 헷갈리네요 ㅠ

1 답변

  • 좋아요

    1

    싫어요
    채택 취소하기
    inline fun <T, R> T.run(block: T.() -> R): R {
        return this.block()
    }
    

    이 코드에서 T.() -> R 에 대해서는 Function TypesFunction literals with receiver 를 살펴보시면 이해가 빠르실 것 같습니다!

    Function literals with receiver 은 암시적으로 this 로 표현 할 수 있으며 해당 리시버 객체의 멤버에 접근이 가능한 특징을 갖습니다. this 는 생략 가능하므로 this.block()block() 은 같은 의미로 볼 수 있습니다. 언급 하셨듯이 확장 함수와 유사한 특성이 있습니다만 확장 함수를 의미 하는 것은 아닙니다.

    따라서, this.block()block() 모두 사용 가능하며 확장 함수를 매개변수로 호출 할 수는 없습니다.

    하기와 같이 Function Type 으로 호출은 가능 하겠네요 :)

    val op: String.() -> Unit = { println() }
    "Hello".run(op)
    
    • (•́ ✖ •̀)
      알 수 없는 사용자
    • 감사합니다 선생님! 저는 왜 prinlnt()이 `T.() -> R` 타입이 아니냐 라고 질문 드렸는데, 사실 `block`이 확장함수를 매개변수로 받는 것이 아니라, T.()이라는 확장함수의 본문내용?을 받는 것이라고 생각해야하나요? 그래서 그 본문은 block이라는 확장함수의 내용이니까, println(this)가 사용가능했던 것이구요.. 맞나요..? codeslave 2021.6.29 03:09

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)