[Kotlin] apply, with, let, also, run, 범위 지정, 수신 객체 지정 람다, 확장함수
2021. 6. 21. 11:15ㆍ모바일/Android_Kotlin
[Kotlin] apply, with, let, also, run, 범위 지정, 수신 객체 지정 람다, 확장함수
확장함수란?
- Extension functions(확장 함수)는 기존에 정의된 클래스에 함수를 추가하는 기능입니다. 자신이 만든 클래스는 새로운 함수가 필요할 때 쉽게 추가할 수 있는데요. Standard Library 또는 다른 사람이 만든 라이브러리를 사용할 때 함수를 추가하기가 매우 어렵습니다.
확장함수 정의법
fun List<Int>.getHigherThan(num: Int): List<Int> {
val result = arrayListOf<Int>()
for (item in this) {
if (item > num) {
result.add(item)
}
}
return result
}
출처 : https://codechacha.com/ko/kotlin-extension-functions/
수신 객체 지정 람다란?
- 함수 작성 시 사용하는 객체를 반복해서 명시하는 경우가 많다.
- 이런 객체들을 함수안에서 명시 하지 않고 람다 본문 안에서 다른객체의 메소드를 호출할 수 있게 하는 람다
범위 지정 함수란?
- 2가지 구성 요소를 갖는다.
- 수신객체
- 수신 객체 지정 람다
5가지 함수
inline fun <T, R> with(receiver: T, block: T.() -> R): R {
return receiver.block()
}
inline fun <T> T.also(block: (T) -> Unit): T {
block(this)
return this
}
inline fun <T> T.apply(block: T.() -> Unit): T {
block()
return this
}
inline fun <T, R> T.let(block: (T) -> R): R {
return block(this)
}
inline fun <T, R> T.run(block: T.() -> R): R {
return block()
}
with
- Non-nullable (Null 이 될수 없는) 수신 객체
- 명시적으로 수신객체가 지정된다
return with(stringBuilder){
for(letter in 'A'..'Z'){
this.append(letter)
}
append("알파벳")
this.toString()
}
//////
fun alphablet(): String = with(StringBulder()){
for(letter in 'A'...'Z'){
append(letter)
}
append("알파벳")
toString()
}
- with(stringBuilder,{....}) 와 같다
with 2
class Person {
var name: String? = null
var age: Int? = null
}val person: Person = getPerson()
print(person.name)
print(person.age)
다음 코드는 person 의 중복 사용을 제거하기 위해 범위 지정 함수 with 를 사용한다는 점을 제외하고는 위와 동일합니다.
val person: Person = getPerson()
with(person) {
print(name)
print(age)
}
apply
- 항상 자신에게 전달된(수신) 객체를 반환한다.
- with함수와 거의 같다
- 수신 객체 람다 내부에서 수신 객체의 함수를 사용하지 않고 수신 객체 의 프로퍼티 만을 사용
- 객체 초기화시 주로 사용
- apply는 객체의 property 값을 적용할 때 사용한다
fun alphabet(): String = StringBuilder().apply{
for(letter in 'A'...'Z'){
append(letter)
}
append("알파벳")
}.toString()
with vs apply
- With returns the last line in the lambda as the result of the expression.
- with는 람다식 내의 마지막 문장라인을 돌려준다
- Apply returns the object that was passed in as the receiver as the result of the lambda expression.
- apply는 리시버로 보낸 객체를 돌려준다
also
- 객체의 사이드 이펙트 확인
- 수신 객체의 프로퍼티에 데이터를 할당하기 전에 해당 데이터 유효성 검사 시 유용하게 사용
- 수신 객체 람다가 전달된 수신 객체 사용x
- 수신 객체의 속성 변경하지 않고 사용
// 범위 지정 함수를 사용하지 않는 예
println(person.age)
println(person.name)
// 범위 지정 함수를 사용하는 예 1
with(person) {
println(age)
println(name)
}
// 범위 지정 함수를 사용하는 예 2
person.also {
println(it.age)
println(it.name)
}
let
- 지정된 값이 null이 아닌 경우에 코드 실행(null 이면 프로그램이 죽지는 않고 다음 코드 실행)
val stocks : 보유종목가져오기함수()
stocks?.let{
}?:run{
}
- 단일 지역 변수의 범위를 제한 하는경우
run
- 어떤 값을 계산할 필요가 있거나 여러개의 지역 변수의 범위를 제한하려면 run 을 사용합니다.
run()
은 이미 생성된 객체에 연속된 작업이 필요할 때 사용
val inserted: Boolean = run {
// person 과 personDao 의 범위를 제한 합니다.
val person: Person = getPerson()
val personDao: PersonDao = getPersonDao() // 수행 결과를 반환 합니다.
personDao.insert(person)
}
fun printAge(person: Person) = person.run {
// person 을 수신객체로 변환하여 age 값을 사용합니다.
print(age)
}
run 을 사용하지 않는 동일한 코드는 다음과 같습니다.
val person: Person = getPerson()
val personDao: PersonDao = getPersonDao()
val inserted: Boolean = personDao.insert(person)
fun printAge(person: Person) = {
print(person.age)
}
run2
data class WHAT(var name: String, var age: Int)
fun main() {
val v = run {
val w = WHAT("Jackass", 16)
w
}
println(v)
val vv = v.run {
name = "Dip2K"
age = 43
"Good day !"
}
println(v)
println(vv)
}
//출력
WHAT(name=Jackass, age=16)
WHAT(name=Dip2K, age=43)
Good day !
'모바일 > Android_Kotlin' 카테고리의 다른 글
[kotlin] 코틀린을 다루는 기술 — 4장 재귀, 공재귀, 메모화 (0) | 2021.06.21 |
---|---|
[kotlin] High-Order-Function (0) | 2021.06.18 |
[kotlin] inline , noinline, crossline function (0) | 2021.06.18 |
[kotlin] class, object, companion object (0) | 2021.06.17 |
[kotlin] 함수 리터럴 (with receiver) (0) | 2021.06.17 |