Kotlin

[Kotlin] Scope function - let, with, run, apply, also

빡수수 2023. 12. 6. 20:54

서론

Kotlin에는 다양한 Scope function이 있다. 객체를 사용할 때 명령문을 블럭{}으로 묶어서 간결하게 사용할 수 있게 해 주는 함수들이다.
오늘은 Scope function인 let, with, run, apply, also에 대해 정리해보려 한다.

 

Scope function?

Kotlin 표준 라이브러리에는 객체 내부에서 코드를 실행할 수 있는 여러 함수가 제공된다. 그들 중 일부는 람다 표현식이 제공되고, 임시 스코프가 형성된다. 이 스코프에서는 객체의 이름을 사용하지 않고 객체에 접근이 가능하다. 

it, this 등을 활영하여 객체에 접근할 수 있도록 해주는? 함수가 Scope function이다.
Scope function은 새로운 기술적 기능을 도입하지 않지만 코드를 더 간결하고 읽기 쉽게 즉, 가독성을 높여준다.

Function Object reference Return value Is extension function
let it Lambda result  YES
run this Lambda result YES
run - Lambda result NO : called without the context object
with this Lambda result NO : takes the context object as an argument
apply this Context object YES
also it Context object YES

 

위 내용을 정리하면 크게 2가지로 분류된다.

  • Object reference 호출 방식이 it인지, this인지
  • return value가 Lambda result인지, Object reference인지

공식 페이지에서 소개하는 간단한 가이드

  • nullable이 아닌 객체에 대해 람다 실행 : let
  • 로컬 범위의 변수로 표현식 소개 : let
  • 객체 구성 : apply
  • 객체 구성 및 결과 계산 : run
  • 표현식이 필요한 명령문 실행 : 비확장 run
  • 추가 효과 : also
  • 객체에 대한 그룹화 함수 호출 : with

Scope function을 사용하면 코드가 더 간결해질 수 있지만 과도하게 사용한다면 오히려 코드를 더 읽기 어렵게 만들고 오류가 발생할 수 있으니 주의하자!

let

  • context object : it
  • return value : Lambda result

null이 아닌 값으로만 코드 블록을 실행시키고 싶을 때 자주 사용되며 null이 아닌 객체에 대해 작업을 수행하려면,

safe call(?.) 사용

// let 미사용 시
val numbers = mutableListOf("one", "two", "three", "four", "five")
val resultList = numbers.map { it.length }.filter { it > 3 }
println(resultList)   

// let 사용 시
val numbers = mutableListOf("one", "two", "three", "four", "five")
numbers.map { it.length }.filter { it > 3 }.let { 
    println(it)
    // and more function calls if needed
}

// safe call
val str: String? = "string"

val result = str?.let { //safe call
	println("safe call 사용 가능, str: $str")
}

 

with

  • context object : this
  • return value : Lambda result

이미 생성된 context object 객체를 인자로 받아서 사용하는 것이 효율적일 때 사용

val numbers = mutableListOf("one", "two", "three")
with(numbers) {
    println("'with' 는 ${this} 로 참조합니다.")
    println("${size}개의 요소를 포함합니다.")
}

val numbers = mutableListOf("one", "two", "three")
val firstAndLast = with(numbers) {
    "첫번째 요소는 ${first() 입니다.}," +
    "마지막 요소는 ${last() 입니다.}"
}
println(firstAndLast)

 

run

  • context object : this
  • return value : Lambda result

with와 유사하지만 safe call(?.)을 붙여서 null 체크도 가능하기 때문에 자주 사용됨

val person = Person("soo", 27).run {
	println("${name}는 ${age}살이다.")
	this.age + 1
}

println("내년 나이는 ${person}살이다.")

//출력값
//soo는 27살이다.
//내년 나이는 28살이다.

 

apply

  • context object : this
  • return value : context object

객체 초기화 시에 가장 많이 사용됨

val person = Person("soo").apply {
	age = 27
}

 

also

  • context object : it
  • return value : context object

기존 객체를 수정하거나 변경하지 않고, 디버깅을 위한 로깅 등의 추가적인 작업을 할 때 사용

val numbers = mutableListOf("one", "two", "three")
numbers
    .also { println("새 항목 추가하기 전 리스트 요소들: $it") }
    .add("four")

 

Reference

 

Scope functions | Kotlin

 

kotlinlang.org

 

코틀린(Kotlin)의 Scope Function(let, with, run, apply, also) 정리

Scope Function 이라는 함수명에서 알 수 있듯이, 이 함수들을 람다식을 이용해서 호출하면 일시적인 Scope(범위)가 생기게 되고, 이 범위 안에서는 전달된 객체에 대해 "it" 또는 "this" 라는 Context Object

0391kjy.tistory.com