-
[Kotlin 코틀린] Scope function - apply, with, let, also ,runKotlin 2021. 8. 28. 23:11728x90
Scope Function
Kotlin 표준 라이브러리에는 제공된 람다 식이 있는 object 에서 scope function 을 호출하면 임시 범위가 형성된다. 이 범위에서는 이름 없이 object 에 액세스할 수 있다. 코드를 더 간결하고 읽기 쉽게 만들 수 있다.
Function 개체 참조 (Object reference) 반환 값 (Return value) 확장 기능 여부 (Is extension function) let it Lambda result 예 run this Lambda result 예 run - Lambda result 아니오 : Context object 없이 호출 with this Lambda result 아니오 : Context object 를 인수로 사용 apply this Context Object 예 also it Context Object 예 Scope Function 에는 두 가지 주요 차이점이 있다.
Context Object 참조
- this : run, with, apply 는 Context Object 를 lambda receiver 인 'this' 로 참조한다. 따라서 람다식 안에서는 일반 클래스 멤버처럼 사용할 수 있다.
val adam = Person("Adam").apply { age = 20 // same as this.age = 20 or adam.age = 20 city = "London" } println(adam)
- it : let, also 는 lambda argument 처럼 'it' 으로 참조한다. 따로 전달 인자명을 지정할 수도 있고, 지정하지 않으면 기본적으로 'it' 으로 접근한다. 하지만 'this' 처럼 object 의 함수나 프로퍼티를 호출할 때 'this' 처럼 암시적으로 사용할 수 는 없다.
fun getRandomInt(): Int { return Random.nextInt(100).also { writeToLog("getRandomInt() generated value $it") } } val i = getRandomInt()
Return value
- Context Object : apply 와 also 는 코드 블록의 context object 를 반환한다. 따라서 같은 객체에 대한 call chain 을 가질 수 있고, return 문에 사용될 수 있다.
val numberList = mutableListOf<Double>() numberList.also { println("Populating the list") } .apply { add(2.71) add(3.14) add(1.0) } .also { println("Sorting the list") } .sort()
- Lambda result : let, run, with 은 lambda result 를 반환한다. 추가적으로 이 return value 를 무시하고 변수를 위한 일시 범위를 생성하는데 사용할 수도 있다.
val numbers = mutableListOf("one", "two", "three") with(numbers) { val firstItem = first() val lastItem = last() println("First item: $firstItem, last item: $lastItem") // First item: one, last item: three }
let
- it / lambda result
- call chains 의 결과 값에 하나 이상의 함수를 호출할 때 사용한다.
val numbers = mutableListOf("one", "two", "three", "four", "five") numbers.map { it.length }.filter { it > 3 }.let { println(it) } val numbers = mutableListOf("one", "two", "three", "four", "five") numbers.map { it.length }.filter { it > 3 }.let(::println) // [5, 4, 4]
- ?. 를 사용하여 non-null 값일 때만 코드 블록을 실행시킬 때 자주 사용된다.
with
- this / lambda result / 인자로 context object 전달
- lambda result 반환 없이 코드 블록 내에서 함수를 호출할 때 사용할 것을 추천
- " with this object, do the following."
val numbers = mutableListOf("one", "two", "three") with(numbers) { println("'with' is called with argument $this") println("It contains $size elements") }
run
- this / lambda result / with 과 동일하지만 context object 의 확장함수로 호출
- 코드 블록 내에 객체 초기화와 반환 값 계산을 둘다 담고 있는 경우에 유용하다.
val service = MultiportService("https://example.kotlinlang.org", 80) val result = service.run { port = 8080 query(prepareRequest() + " to port $port") } // the same code written with let() function: val letResult = service.let { it.port = 8080 it.query(it.prepareRequest() + " to port ${it.port}") }
apply
- this / context object
- 주로 객체 초기화 시에 많이 사용된다.
- " apply the following assignments to the object."
val adam = Person("Adam").apply { age = 32 city = "London" } println(adam)
also
- it / context object
- context object 를 인자처럼 사용하는 액션에 유용하다.
- object 의 프로퍼티나 함수에 대한 참조가 아닌 object 자체에 대한 참조가 필요한 액션에 유용하다.
val numbers = mutableListOf("one", "two", "three") numbers .also { println("The list elements before adding new one: $it") } .add("four")
https://kotlinlang.org/docs/scope-functions.html
728x90'Kotlin' 카테고리의 다른 글
[Kotlin 코틀린] 고차함수와 람다(High Order Function & Lambda) (0) 2021.01.09 [Kotlin 코틀린] 추상클래스와 인터페이스 (Abstract Class & Interface) (0) 2021.01.08 [Kotlin 코틀린] 타입추론(Type inference)과 함수 (0) 2021.01.06 [Kotlin 코틀린 기초] 변수 및 자료형 (Nullable & Non-Nul (0) 2021.01.06