계발자 블로그

[Kotlin] Scope Function 본문

Kotlin

[Kotlin] Scope Function

더구더구 2022. 3. 30. 22:55

코틀린을 사용하면서 많이 등장 하길래 한번쯤 제대로 정리 해 봐야겠다 생각해서

오늘은 코틀린의 스코프 함수에 대해 알아보겠습니다.

Scope Function이란?

객체의 컨텍스트 내에서 코드 블럭을 실행할 수 있도록 해주는 함수입니다.

Scope function은 이름처럼 Scope(범위)가 생깁니다.

해당 범위에서 특정 객체의 컨텍스트를 가지고 동작을 하는 것입니다.

람다식과 동일하게 작성을 하며, 이 범위 내에서는 객체의 이름이 없어도 객체에 접근할 수 있습니다.

let, with, run, apply, also가 이에 해당됩니다.

 

Scope function에는 두가지 차이점이있습니다.

1. Context Object를 참조하는 방법(this, it)

2. Return value

 

1. Context Object

scope function 람다식 내에서 Context Object는 실제 객체명 대신, it 또는 this 키워드로 접근합니다.

 

this 

  • run, with, apply는 this를 참조합니다
  • 람다식 안에서는 일반 클래스 멤버처럼 사용할 수 있습니다.
  • this는 생략할 수 있지만, 동일한 이름의 멤버가 있을 경우 구별할 수가 없기 때문에 가급적이면 this를 붙여서 사용하는 것이 좋습니다.

it

  • let, also는 it을 참조합니다.
  • 따로 전달 인자명을 지정할 수 있고, 지정하지 않으면 기본적으로 it으로 접근하게 됩니다.

2. Return value

apply, also는 Context Object를 반환합니다.

let, run, with는 Lambda Result(람다식 결과)를 반환합니다.

 

2-1. Context Object

  • 체인 형식으로 계속적인 호출이 가능합니다.
  • Context Object를 반환하는 함수의 return문에도 사용할 수 있습니다.

2-2. Lambda Result

  • 결과를 변수에 할당하거나, 결과에 대해 추가적인 작업 등을 수행할 때 사용할 수 있습니다.
  • 반환 값을 무시하고 바로 람다식을 사용하여, 임시 범위를 만들어서 사용할 수도 있습니다.

apply

Context Object : this

Return value : context object

 

인스턴스 자신을 바로 반환해 주며 객체 생성 하자마자 조작한 다음에 객체 바로 변수에 넣기 가능

인스턴스를 새로 만들고 특정 변수에 할당하기 전에 초기화 작업을 해주는 스코프

val person = Person("홍길동").apply {	
			age = 30
		}

 

also

Context Object : it

Return value : context object

 

also는 기존 객체를 수정하거나 변경하지 않고, 디버그, 로깅 등의 부가적인 작업을 할 때 사용합니다.

val numbers = mutableListOf("one", "two", "three")
numbers.also {
	println("add 하기 전 print: $it")
             }
       .add("four")

 

let

Context Object : it

Return value : lambda result

 

객체 결과값에 하나 이상의 함수를 호출하는데 사용할 수 있습니다.

let 블럭 안에는 non-null만 들어올 수 있어 non-null 체크 시에 유용하게 쓸 수 있습니다.

/** 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)
    // 추가적인 함수 호출 가능
} 

//null 체크
val str: String? = "Hello"   

val length = str?.let { //안전한 호출 Safe Call
    println("let() 호출 $it")        
}

 

run

Context Object : this

Return value : lambda result

 

이미 생성된 context 객체를 사용할 때 호출되며 run을 확장함수가 아닌 단독으로 사용하여 block으로 값을

만들어 내는데도 사용할 수 있습니다.

Safe Call을 지원합니다.

val objectString: String = MappingService("sabarada", 15).run {
            this.incrementAge()
            this.toString()
        }

println(objectString) // 결과 : 이름 = karol, 나이 = 16
val resultString: String = run {
    val first: String = "sabarada"
    val second: String = "Karol"

    "$first is $second"
}

println(resultString) // 결과 : sabarada is Karol

 

 

with

Context Object : this

Return value : lambda result

 

run과 거의 동일하지만 Safe Call을 지원하지 않습니다.

블럭의 return 값이 필요하지 않을 때 사용합니다.

주로 객체의 함수를 여러개 호출할 때 그룹화 하는 용도로 사용됩니다.

val person = Person("James", 56)
with(person) {
    println(name)
    println(age)
    //자기자신을 반환해야 하는 경우 it이 아닌 this를 사용한다
}

// James
// 56

 

 

참고 :

https://jade314.tistory.com/entry/let-apply-run-with-%ED%95%A8%EC%88%98

https://blog.yena.io/studynote/2020/04/15/Kotlin-Scope-Functions.html

https://velog.io/@hwi_chance/Kotlin-Scope-Functions

'Kotlin' 카테고리의 다른 글

[Kotlin] 코틀린 Companion Object  (0) 2023.03.01
[Kotlin] Kotlin Property (코틀린 프로퍼티)  (0) 2023.03.01
Coroutine  (0) 2022.09.27
[Kotlin] Collection  (0) 2021.12.10
[Coroutine] LifecycleScope  (0) 2021.10.28