본문 바로가기

Language/Kotlin

코틀린 표준함수(apply, let, run, with, also, takeIf)

반응형

이 포스팅은 빅 너드 랜치의 코틀린 프로그래밍 책을 공부하면서 요약한 내용이다.

 

코틀린의 표준 함수는 내부적으로 확장함수이며 확장함수를 실행하는 주체를 수신자 또는 수신자 객체라고 한다. 따라서 확장 함수가 호출될 때 수신자 객체의 참조가 확장 함수로 전달된다.

1. apply

apply 함수는 구성함수로서 우리가 사용할 객체를 구성할때 반복되는 코드의 양을 줄이기 위해 사용된다. 

// 일반코드
val f = File("abc.txt")
f.setReadable(true)
f.setWritable(true)

// apply를 사용한다면?
val f = File("abc.txt").apply {
	setReadable(true)
	setWritable(true)
}

 apply 함수는 람다 내부의 모든 함수 호출이 수신자 객체에 관련되어 호출된다. 따라서 f라는 파일 객체를 적지 않아도 된다.

 

2. let

let은 이 함수의 인자로 전달된 람다를 실행한 후 결과를 반환해 준다.  또한 it 키워드를 사용해서 let을 호출한 수신자 객체를 참조할 수 있다. 다음 예제는 let 함수를 사용하여 첫 번째 인자를 제곱한 후 변수에 담는 작업이다.

// 일반 코드
val first = listof(1,2,3).first()
val Squared = first * first


val Squared = listOf(1, 2, 3).first().let{
	it * it
}

* apply와 let의 차이점

let은 수신자 객체를 람다로 전달한다. 그러나 apply는 아무것도 전달하지 않는다. 또한, apply는 람다의 실행이 끝나면 현재의 수신자 객체를 반환한다. 반면에 let은 람다에 포함된 마지막 코드 줄의 실행 결과를 반환한다.

3. run

run은 apply와 동일한 연관 범위를 제공한다. 그러나 apply와 다르게 run은 수신자 객체를 반환하지 않고 let처럼 마지막 변수가 반환된다.

// 일반코드
val strTest = "wefwefwefefqqwwf"

fun nameIsLong(name : String) = name.length >= 20

fun playerCreateMessage(nameTooLong : Boolean) : String{
    return if(nameTooLong){
        "이름이 너무 길다~ 줄여라"
    }
    else {
        "적당한 이름 길이네"
    }
}

// run 함수를 사용했을 때
fun main(args : Array<String>)
{
	// 일반 코드
	println(playerCreateMessage(nameIsLong(strTest)))


	// run 함수를 사용했을 때
    strTest
        .run(::nameIsLong)
        .run(::playerCreateMessage)
        .run(::println)
}

 

4. with

with은 run과 동일하게 동작하지만 호출 방식이 다르다. 지금까지 보았던 표준 함수들은 수신자 객체로 호출하였다. 그러나 wit은 수신자 객체를 첫 번째 매개변수의 인자로 받는다. 

val nameTooLong = with("wfwefqqfwwf") {
	length >= 20
}

with은 다른 함수와 비교했을 때 일관성이 떨어지므로 with 대신 run 함수를 사용할것을 권장한다.

 

5. also

also 함수는 let 함수와 매우 비슷하게 동작한다. al도 let처럼 자신을 호출한 수신자 객체를 람다의 인자로 전달한다. 그러나 let과 also는 한가지 큰 차이점이 있다. also는 람다의 결과를 반환하지 않고 수신자 객체를 반환한다.

    //일반코드
    var strTest = "qwfwqfwqf"
    println(strTest)
    println(strTest.length)
    
    //also 사용했을 때
    var strTest = "qwfwqfwqf"
        .also { println(it) }
        .also { println(it.length)}

also는 람다의 결과 대신 수신자 객체를 반환하므로 원래의 수신자 객체로 함수를 연쇄 호출할 수 있다.

 

6. takeIf

코틀린의 또 다른 표준 함수로 takeIf가 있다. takeIf는 다른 표준 함수와 약간 다르게 동작한다. 람다에 제공된 조건식을 실행한 후 그 결과에 따라 true 또는 false를 반환한다. 만일 조건식의 결과가 true면 수신자 객체가 반환되며 false면 null이 반환된다.

// 일반코드
val f = File("myfile.txt")
val fileContents = if(file.canRead() && file.canWrite()){
	file.readText()
} else{
	null
}

// takeIf를 사용했을 때
val fileContents = File("myfile.txt").takeIf{it.canRead() && it.canWrite()}?.readText()

 

7. takeUnless

takeIf를 보완하는 함수로 takeUnless가 있다. takeUnless 함수는 takeIf와 똑같다. 단, 우리가 지정한 조건식이 false일 때 원래 값을 반환한다는 점이 다르다. 

val fileContents = File("myfile.txt").takeUnless{it.isHidden}?.readText()

 

takeIf : 만일 조건이 true면 해당 값을 반환해라

takeUnless : 만일 조건이 true가 아니면 해당 값을 반환해라

 

반응형

'Language > Kotlin' 카테고리의 다른 글

코틀린 Data Class  (0) 2019.12.26
코틀린 split 신기함  (0) 2019.11.20
코틀린 리스트 (MutableList, List)  (0) 2019.11.20
코틀린 Null (안전 호출 연산자, non-null 단언 연산자)  (0) 2019.11.14
코틀린의 특징  (0) 2019.08.20