공감 및 댓글은 포스팅 하는데 아주아주 큰 힘이 됩니다!! 포스팅 내용이 찾아주신 분들께 도움이 되길 바라며 더 깔끔하고 좋은 포스팅을 만들어 나가겠습니다^^
|
지난 포스팅에서 Scope Functions 에 대해 공부했는데요.
2019/07/16 - [코틀린(Kotlin)] - 코틀린 Scope Functions - [ let, run, with, apply, also ]
이번 포스팅에서는 각 함수의 사용 예제에 대해 보겠습니다.
let
context object를 it argument로 사용할 수 있습니다.
반환 값은 람다 결과입니다.
call chains의 결과에서 하나 이상의 함수를 호출하는데 사용할 수 있습니다.
// 예제 1
val numbers = mutableListOf("one", "two", "three", "four", "five", "six")
val result = numbers.map { it.length }.filter { it > 3 }
println(result)
numbers.map { it.length }.filter { it <= 3 }.let { println(it) }
// 람다 대신에 메소드 참조를 사용할 수도 있습니다.
numbers.map { it.length }.filter { it <= 3 }.let(::println)
// 예제 2
fun processNonNullString(str: String){}
val str: String? = "Hello"
val length = str?.let {
println("let() called on $it")
processNonNullString(it)
it.length
}
// 예제 3
val numbers2 = listOf("one", "two", "three", "four")
val modifiedFirstItem = numbers2.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'")
=======================================================
=======================================================
with
확장함수가 아닙니다. context object는 argument로 사용되고 람다의 내부에서는
receiver(this)로 사용됩니다. 반환 값음 람다의 결과값입니다.
공식 문서에서는 with 함수는 람다의 결과를 제공하지 않고 context object에서
함수를 호출할 것을 권장한다고 합니다.
fun main() {
val numbers = mutableListOf("one", "two", "three")
with(numbers) {
println("'with' is called with argument numbers")
println("It contains $size elements")
}
val numbers2 = mutableListOf("one", "two", "three")
val firstAndLast = with(numbers2) {
"The first element is ${first()} and the last element is ${last()}"
}
println(firstAndLast)
}
with 의 argument 가 this 되게 때문에 해당 argument 가 가지는 멤버를 바로
호출할 수 있습니다. 위 예제에 경우 MutableList() 이기 때문에
size, fist(), last() 등의 멤버를 호출했습니다.
==============================================================================================================
run
context object 가 receiver 로 사용됩니다. 반환 값은 람다의 결과 값입니다.
run은 with와 같지만, let처럼 호출합니다.
run은 context object 의 초기화와 계산이 같이 들어갈 때 사용하면 유용합니다.
class MultiportService(var url: String, var port: Int) {
fun prepareRequest(): String = "Default request"
fun query(request: String): String = "Result for quest '$request'"
}
fun main() {
val service = MultiportService("https://www.abcdefg.com", 80)
val result = service.run {
port = 8000
query(prepareRequest() + "to port $port")
}
val letResult = service.let {
it.port = 8080
it.query(it.prepareRequest() + "to port ${it.port}")
}
println(result)
println(letResult)
}
그리고 비확장 함수로도 사용할 수 있습니다.
val hexNumberRegex = run {
val digits = "0-9"
val hexDigits = "A-F-a-f"
val sign = "+-"
Regex("[$sign]?[$digits$hexDigits]+")
}
for (match in hexNumberRegex.findAll("+1234 -FFFF not-a-number")) {
println(match.value)
}
실행은 각자 ㅎ
==============================================================================================================
apply
data class ApplyUser(var name: String, var age: Int = 0, var country: String = "")
fun main() {
// Context object를 receiver(this)로 사용합니다.
// 반환 값은 사용된 object 자기 자신입니다.
val thomas = ApplyUser("Thomas Park").apply {
age = 28
country = "Republic of Korea"
}
println(thomas)
}
=======================================================
also
fun main() {=======================================================
// context object는 argument(it) 으로 사용됩니다. 반환값은 apply 와 마찬가지로 자기 자신입니다.
// also 는 context object 를 argument로 취하는 작업을 할 때 사용하는 것이 좋습니다.
val numbers = mutableListOf("one", "two", "three")
numbers.also { println("The list element before adding new one $it") }.add("four")
}
Function |
Object reference |
return value |
Is extension function |
let |
it |
Lambda result |
Yes |
run |
this |
Lambda result |
Yes |
ryn |
- |
Lambda result |
No: called without the context object |
with |
this |
Lambda result |
No: takes the context object as an argument. |
apply |
this |
Context Object |
Yes |
also |
it |
Context Object |
Yes |
fun main() {
val number = Random.nextInt(100)
val evenOrNull = number.takeIf { it % 2 == 0 }
val oddOrNull = number.takeUnless { it % 2 == 0 }
println("evenOrNull = $evenOrNull | oddOrNull = $oddOrNull")
val str = "Hello"
val caps = str.takeIf { it.isNotEmpty() }?.toUpperCase()
println(caps)
}
'코틀린(Kotlin)' 카테고리의 다른 글
코틀린(kotlin) : 코틀린의 Collections - List, Set, Map (0) | 2019.08.21 |
---|---|
코틀린(kotlin) : 코틀린의 Collections - read only, mutable (1) | 2019.08.21 |
코틀린 Scope Functions - [ let, run, with, apply, also ] (0) | 2019.07.16 |
이클립스에 코틀린 플러그인 설치하기 (0) | 2019.07.16 |
자바의 Collections를 대체하는 방법 코틀린 Collections.sort(), Collections.shuffle() (0) | 2019.07.05 |