상세 컨텐츠

본문 제목

[Kotlin] 표준함수

Programming language/Kotlin

by choiDev 2020. 12. 6. 00:25

본문

표준 함수란?

  - Kotlin에서 보편적으로 사용되는 유틸리티 함수이며, 람다를 인자로 받아 동작한다.

  - 이 포스팅에선 (apply, let, run with, also, takeIf) 6개의 사용 방법을 알아본다

  - Kotlin 표준 함수는 내부적으로 확장 함수(extension function)이며, 확장 함수를 실행하는 주체를
   수신자 또는 수신자 객체라고 한다.

  - 따라서 확장 함수가 호출될 때 수신자 객체의 참조가 확장 함수로 전달된다. 

 

apply

  - apply 함수는 사용할 객체를 생성 시 생성할 객체를
    apply 수신자 객체에 전달하고, 수신자 객체의 할 일이 종료되면 객체를 반환합니다.

  - 특정 객체를 생성하면서, 객체를 초기화 할 코드가 있는 경우 사용됩니다.

  - 아래 코드를 보면 apply 함수를 사용하면 하나의 블럭에서 객체의 초기화를 진행하여
    가독성에 도움이 되는 걸 확인 할 수 있다.

  - 또한 apply 람다 내부의 모든 호출은 수신자에 관련되어 호출되므로
    이것을 연관 범위(relative scoping) 혹은 암시적 호출(implicitly called)이라고 한다.

fun main(args: Array<String>) {
    //apply 함수를 사용하여 User객체를 생성한 예제
    val user:User = User().apply {
        name = "Choi"
        age = 20
        sex = 'M'
    }

    //apply 함수 없이 User객체를 생성한 예제
    val user2:User = User()
    user.name = "Choi"
    user.age = 20
    user.sex ='M'
}

 

let

  - let 함수는 함수에 인자로 전달된 람다를 실행한 후 결과를 반환해 준다.

  - let 함수는 어떤 종류의 수신자 객체에서도 호출 가능하다.

  - it 키워드를 사용해서 let을 호출한 수신자 객체를 참조할 수 있다.

//List에 저장된 첫번째 요소의 제곱을 구하는 코드
fun main(args: Array<String>) {
    val firstItemSquared:Int = listOf(1,2,3).first().let {
        it * it
    }

    println(firstItemSquared)
}

  - 만일 위에서 let 함수를 사용하지 않았다면 별도의 변수를 지정해줘야 한다.

fun main(args: Array<String>) {
    val firstItem:Int = listOf(1,2,3).first()
    val firstItemSquared = firstItem * firstItem

    println(firstItemSquared)
}

  - null 복합 연산자와 같이 사용하면 null 가능 타입에서 발생될수 있는 예외를 방지하며 기본값을 지정 할 수 있다.

fun main(args: Array<String>) {
    var name: String? = null
    name = name?.let {
        "이름이 $it 님 이시군요"
    } ?: "앗 현재 이름이 없으시군요."

    println(name)
}

 

run

  - run은 람다의 실행 결과를 반환한다.

  - run은 수신 객체에서 호출한 run과 , 수신 객체 없이 호출된 run의 형태가 있습니다.

  - run 어떤 값을 계산할 필요가 있거나, 여러개의 지역변수 사용범위를 제현하기 위해 사용합니다.

fun main(args: Array<String>) {
    val isHaveName: Boolean = run { //이름이 있는지 판단하는 용도로 User 객체가 필요하면
        val user: User = User()     // run으로 범위를 지정해 사용 할 수 있다.
        user.name != ""
    }

    User().run{         //수신자 객체를 대상으로 run함수를 사용하면
        println(name)   //수신자 객체의 요소를 사용할 수 있다.
    }
}

 

with

  - with은 수신자 객체를 첫 번째 매개변수 인자로 받는다.  (아래 예제 참조)

fun main(args: Array<String>) {
    val isMsgToLong = with("This message is .... long.. .... . . . . "){
        length >= 20
    }

    println(isMsgToLong)
}

 

also

  - also는 let처럼 자신을 호출한 수신자 객체를 람다의 인자로 전달한다.

  - also는 let과는 달리 람다의 결과가 아닌 수신자 객체를 반환한다. 

  - 아래 코드와 같이 서로 다른 처리를 also를 사용해 연쇄 호출할 수 있다. 

fun main(args: Array<String>) {
    val user:User = User().also{
        it.name = "Choi"
    }.also {
        it.age = 28
    }.also {
        println("${it.name} ${it.age}")
    }
}

 

takeIf

  - 람다에 제공된 조건식을 실행한 후 그 결과에 따라 true 또는 false를 반환한다.
    조건식의 결과가 true이면 수신자 객체가 반환되며 false이면 null이 반환된다.

fun main(args: Array<String>) {
    val user:User? = User().takeIf { it.name == "Choi" }
    println(user?.name)
    println(user?.age)
}

 

takeUnless

  - takeIf를 보완하는 함수이며 구조는 takeIf와 동일하지만 조건식이 false일 때
    수신자 객체를 반환한다는 점이 다르다.

  

표준 함수 정리표

함수 수신 객체를 람다의 인자로 전달하는가? 연관 범위를 제공하는가? 반환
let Yes No 람다의 결과
apply No Yes 수신자 객체
run No Yes 람다의 결과
with No Yes 람다의 결과
also Yes No 수신자 객체
takeIf Yes No 수신자 객체 or null
takeUnless Yes No 수신자 객체 or null

 

'Programming language > Kotlin' 카테고리의 다른 글

[Kotlin] Object & Companion Object  (0) 2021.09.21
[Kotlin] Data Class (데이터 클래스)  (0) 2021.09.21
[Kotlin] 문자열  (0) 2020.12.05
[Kotlin] 익명 함수와 함수 타입  (1) 2020.12.05
[Kotlin] 함수(Function)  (0) 2020.12.04

관련글 더보기