서론
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