Kotlin 기본 개념 정리를 시작해 합니다.
일단, 코틀린의 핵심 함수 Scope functions - let, run, with, apply, also.
유용한 함수에 대한 자세한 설명은 코틀린 사이트에서 잘 나와있다.
kotlinlang.org/docs/scope-functions.html
간단하게 정리해보면, 리턴 값의 차이라고 생각합니다.
- 람다 결과를 리턴 값으로 받는 let, run, with
- 해당 객체 자체를 리턴 값으로 받는 apply, also
간단한 사용 방법
- Null이 아닌 객체 실행 : let
val str: String? = "Hello"
//processNonNullString(str) // compilation error: str can be null
val length = str?.let {
println("let() called on $it")
processNonNullString(it) // OK: 'it' is not null inside '?.let { }'
it.length
}
- Local Scope 에서 읽기 쉽게 변수명 변경 : let
val numbers = listOf("one", "two", "three", "four")
val modifiedFirstItem = numbers.first().let { firstItem ->
println("The first item of the list is '$firstItem'")
if (firstItem.length >= 5) firstItem else "!" + firstItem + "!"
}.toUpperCase()
println("First item after modifications: '$modifiedFirstItem'")
- 객체 구성하기 or 초기화 작업 : apply
val adam = Person("Adam").apply {
age = 32
city = "London"
}
println(adam)
return 값 이라는 측면에서는 also 도 동일한 효과를 낸다.
- 객체 구성 및 결과 계산 : run
val service = MultiportService("https://example.kotlinlang.org", 80)
println(service.run{query(prepareRequest() + " to port $port")})
val result = service.run {
port = 8080
query(prepareRequest() + " to port $port")
}
println(result)
------ 결과 ------
기본 service -> Result for query 'Default request to port 80'
run 적용 result -> Result for query 'Default request to port 8080'
run 적용한 service 의 port 는 8080으로 변경
객체 구성 및 결과 값을 리턴하는 의미에서 run, with, let 모두 같은 결과를 가져온다.
- 식이 필요한 문을 실행할때 : 확장x run
val hexNumberRegex = run {
val digits = "0-9"
val hexDigits = "A-Fa-f"
val sign = "+-"
Regex("[$sign]?[$digits$hexDigits]+")
}
for (match in hexNumberRegex.findAll("+1234 -FFFF not-a-number")) {
println(match.value)
}
- 추가적인 효과를 낼때 : also
val numbers = mutableListOf("one", "two", "three")
numbers
.also { println("The list elements before adding new one: $it") }
.add("four")
----- 결과 -----
also 의 문장 출력 -> The list elements before adding new one: [one, two, three]
numbers 출력 -> [one, two, three, four]
여기서 결과값만 볼때 apply 를 사용해도 무방하나 표현상 also가 맞기에 사용한다는 개념 같다. 지정함수의 차이 말고는 다를게 없기 때문이다.
/**
* Calls the specified function [block] with `this` value as its receiver and returns `this` value.
*
* For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#apply).
*/
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
return this
}
/**
* Calls the specified function [block] with `this` value as its argument and returns `this` value.
*
* For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#also).
*/
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.also(block: (T) -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block(this)
return this
}
- 객체에 있는 함수들을 그룹화 하기 위한 처리 : with
val numbers = mutableListOf("one", "two", "three")
println("$numbers")
println("${numbers.size}")
----- with 사용 -----
with(numbers) {
println("'with' is called with argument $this")
println("It contains $size elements")
}
반응형
'Dev > Kotlin' 카테고리의 다른 글
[kotlin] Loop 문 사용 Tip (0) | 2022.03.25 |
---|---|
Kotlin - 기록 (0) | 2021.10.12 |
Kotlin - unzip (0) | 2020.07.30 |
코틀린 - 고차 함수: 파라미터와 반환 값으로 람다 사용 (요약) (0) | 2018.10.17 |
코틀린 - 연산자 오버로딩과 기타 관례 (요약) (0) | 2018.10.09 |