개발공부/KOTLIN
[KOTLIN] 코틀린 스코프 함수(Scope functions): let, run, with, apply, also
키크니개발자
2023. 10. 21. 19:54
최근에 자바에서 코틀린을 사용하고 있다.
코틀린과 자바에 대해서 비슷하다고는 많이 들었는데
코드를 작성하면서 어떤 상황에서 사용해야되는지 가장 많이 헷깔리는 스코프 함수에 대해서 정리해보려고 한다. 🤓
대표적으로 let, run, with, apply, also가 있다.
스코프 함수에 대해서 살펴보기전에 수신객체에 대해서 알아보자.
수신객체란?
코틀린에서 확장함수나 스코프함수내에서 사용되는 용어이며, 이는 해당 함수가 호출되는 대상 객체를 의미한다.
수신객체 참조 방법 | 스코프 함수 |
this | apply, run |
it | let, also |
기타 | with는 수신객체를 함수의 인자로 받는다. |
수신객체는 this, it을 사용해서 접근할 수 있지만, 따로 전달 인자명을 지정할 수 있다.
// 전달 인자명 지정해서 참조
person.let { value ->
println("이름 : ${value.name}")
}
스코프함수
스코프 함수 | 반환 값 |
apply, also | 수신객체를 반환 |
let, run, with | 람다식 결과를 반환 |
let 이란?
수신객체가 null이 아닌 경우에 코드를 실행할 경우 사용한다.
nullable한 수신객체를 다른 타입의 변수로 변환해야 하는 경우
as-is
val number = getNumber() // null을 반환할 수 있는 함수라고 가정한다.
if (number != null) {
doSomethingWithNumber(number)
}
to-be
getNumber()?.let {
doSomethingWithNumber(it)
}
apply 이란?
수신객체 자신을 반환하며, 객체의 초기화 과정에서 주로 사용된다. (즉, 호출 된 객체를 속성을 변경할 때 사용한다.)
as-is
val person = Person()
person.name = "John"
person.age = 25
person.introduce() // "My name is John and I am 25 years old."를 출력하는 메서드
to-be
val person = Person().apply {
name = "John"
age = 25
}.introduce()
also 란?
수신객체의 프로퍼티를 변경하지 않고 사용할 때 사용한다.
데이터의 유효성 검사, 조회 결과를 다른 작업을 수행한 후 원본 조회 결과를 반환하는 경우 사용한다.
- apply와 많이 헷깔렸지만,
apply는 초기화 되야하는 데이터 수정에 초점을 맞추고,
also는 초기화 된 데이터를 변경하지 않는 선에서 사용할 때에 초점을 맞췄다.
as-is
val numbers = mutableListOf(1, 2, 3)
numbers.add(4)
println("Numbers after adding: $numbers")
val doubled = numbers
to-be
val numbers = mutableListOf(1, 2, 3)
val doubled = numbers.also {
it.add(4)
println("Numbers after adding: $it")
}
run 이란?
주로 객체 초기화와 계산을 동시에 수행할 때 사용한다.
as-is
val text = "Hello, World!"
val lowerCaseText = text.toLowerCase()
val words = lowerCaseText.split(" ")
val numberOfWords = words.size
println("Number of words: $numberOfWords")
to-be
val text = "Hello, World!"
val numberOfWords = text.run {
toLowerCase().split(" ").size
}
println("Number of words: $numberOfWords")
with 이란?
특정 객체의 범위 내에서 여러 메서드나 속성에 접근할 때 사용한다.
- 하지만 보통 사용되지 않는다고 한다. (실제로 사용해본적도 없다.)
with을 사용하려면 보통 run을 사용한다.
run과 동일한 기능을 가지지만 단지 인스턴스를 참조연산자 대신 파라미터로 받는다는 차이를 가지고 있기 때문이다.
as-is
val numbers = mutableListOf("one", "two", "three")
val firstItem = numbers.first()
val lastItem = numbers.last()
println("첫번째 항목: $firstItem, 마지막 항목: $lastItem")
to-be
val numbers = mutableListOf("one", "two", "three")
with(numbers) {
val firstItem = first()
val lastItem = last()
println("첫번째 항목: $firstItem, 마지막 항목: $lastItem")
}
References
반응형