본문 바로가기

개발공부/KOTLIN

[KOTLIN] 코틀린 스코프 함수(Scope functions): let, run, with, apply, also

최근에 자바에서 코틀린을 사용하고 있다.

코틀린과 자바에 대해서 비슷하다고는 많이 들었는데

코드를 작성하면서 어떤 상황에서 사용해야되는지 가장 많이 헷깔리는 스코프 함수에 대해서 정리해보려고 한다. 🤓

 

대표적으로 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

Kotlin in Action

https://0391kjy.tistory.com/25

https://medium.com/@limgyumin/%EC%BD%94%ED%8B%80%EB%A6%B0-%EC%9D%98-apply-with-let-also-run-%EC%9D%80-%EC%96%B8%EC%A0%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94%EA%B0%80-4a517292df29

반응형