일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 끝말잇기
- 지지않는다는말
- 안드로이드
- 자취필수템
- 1일1커밋
- 어떻게 나답게 살 것인가
- 목적중심리더십
- 캐치마인드
- 베드트레이
- 좌식테이블
- T자형인재
- 아비투스
- 슬기로운 온라인 게임
- 목적 중심 리더십
- 한달독서
- 한달브런치북만들기
- 베드테이블
- 재택근무
- 면접
- 한달어스
- 소프시스
- 한단어의힘
- 브런치작가되기
- 북한살둘레길
- 테트리스
- 리얼하다
- 프래그먼트
- 커스텀린트
- 소프시스 밤부 좌식 엑슬 테이블
- 함수형 프로그래밍
- Today
- Total
정상에서 IT를 외치다
[Android, Kotlin] 코틀린의 run, with, apply, let, also 정리 본문
안녕하세요. 블랙집입니다.
그동안 코틀린을 사용하면서 run, with, apply, let, also 를 사용했지만 내용을 한번 정리해 보면 좋을 것 같아 간략히 포스팅을 합니다.
this
run
, with
, and apply
refer to the context object as a lambda receiver - by keyword this
. Hence, in their lambdas, the object is available as it would be in ordinary class functions. In most cases, you can omit this
when accessing the members of the receiver object, making the code shorter. On the other hand, if this
is omitted, it can be hard to distinguish between the receiver members and external objects or functions. So, having the context object as a receiver (this
) is recommended for lambdas that mainly operate on the object members: call its functions or assign properties.
apply , run, with 함수의 블록 안에서는 수신 객체를 this 로 표현됩니다.
1. apply
private val adapter = MainAdapter().apply {
setClickListener(this@MainActivity)
}
위 예제는 어댑터를 생성함과 동시에 클릭 리스너를 초기화 해주는 코드입니다. 특정 객체를 생성함과 동시에 초기화 해줄 때 매우 유용하게 사용합니다.
2. run
apply 함수와 유사하나 apply 함수는 객체를 생성함과 동시에 연속된 작업을 수행할 때 사용하고 run 함수는 이미 생성된 객체의 메서드나 필드를 연속적으로 호출할 때 사용합니다.
recyclerView.run {
layoutManager = LinearLayoutManager(this@MainActivity)
adapter = this@MainActivity.adapter
}
리사이클러뷰의 레이아웃매니저와 어댑터를 연속적으로 호출하는 예 입니다.
recyclerView?.run {
layoutManager = LinearLayoutManager(this@MainActivity)
adapter = this@MainActivity.adapter
}
또한 let 함수와 마찬가지로 ?를 사용하여 널 안정성 검사를 할 수 있습니다.
3. with
run 함수와 기능은 동일하나 리시버로 전달할 객체가 어디에 위치하는지가 다릅니다.
with(recyclerView) {
layoutManager = LinearLayoutManager(this@MainActivity)
adapter = this@MainActivity.adapter
}
여기에 with, let 함수를 사용하여 run 과 동일한 기능을 수행할 수 있습니다.
recyclerView?.let {
with(it) {
layoutManager = LinearLayoutManager(this@MainActivity)
adapter = this@MainActivity.adapter
}
}
it
In turn, let
and also
have the context object as a lambda argument. If the argument name is not specified, the object is accessed by the implicit default name it
. it
is shorter than this
and expressions with it
are usually easier for reading. However, when calling the object functions or properties you don't have the object available implicitly like this
. Hence, having the context object as it
is better when the object is mostly used as an argument in function calls. it
is also better if you use multiple variables in the code block.
let, also 함수의 블록 안에서는 수신 객체를 it 으로 표현됩니다.
4. let
it 을 사용한 경우
intent.getSerializableExtra(KEY_USER)?.let {
if(it is User) {
// kotlin 에서는 자동으로 형 변환이 이뤄집니다.
user = it
}
} ?: throw IllegalAccessException("intent is null")
단일 지역 변수를 지정한 경우
intent.getSerializableExtra(KEY_USER)?.let {userData ->
if(userData is User) {
// kotlin 에서는 자동으로 형 변환이 이뤄집니다.
user = userData
}
} ?: throw IllegalAccessException("intent is null")
이미 생성된 객체를 블록으로 감싸 그 안에서 단일 지역 변수로 사용할 수 있습니다. 또한 ? 와 함께 사용하여 널 안정성 검사를 할 수 있습니다.
5. also
apply 함수와 마찬가지로 객체를 반환하며 let 과 동작이 매우 유사합니다. 하지만 let 에서는 내부 결과를 변화 시킬 수 있지만 also 에서는 변화 시킬 수 없습니다,
private val adapter = MainAdapter().also {
it.setClickListener(this@MainActivity)
}
apply 함수 대신 also 를 사용 할 수 있다
val original = "abc"
// Evolve the value and send to the next chain
original.let {
println("The original String is $it") // "abc"
it.reversed() // evolve it as parameter to send to next let
}.let {
println("The reverse String is $it") // "cba"
it.length // can be evolve to other type
}.let {
println("The length of the String is $it") // 3
}
// Wrong
// Same value is sent in the chain (printed answer is wrong)
original.also {
println("The original String is $it") // "abc"
it.reversed() // even if we evolve it, it is useless
}.also {
println("The reverse String is ${it}") // "abc"
it.length // even if we evolve it, it is useless
}.also {
println("The length of the String is ${it}") // "abc"
}
// Corrected for also (i.e. manipulate as original string
// Same value is sent in the chain
original.also {
println("The original String is $it") // "abc"
}.also {
println("The reverse String is ${it.reversed()}") // "cba"
}.also {
println("The length of the String is ${it.length}") // 3
}
위와 같이 내부 결과를 변화 시킬 수 없다.
Return value
The scope functions differ by the result they return:
apply
andalso
return the context object.let
,run
, andwith
return the lambda result.
These two options let you choose the proper function depending on what you do next in your code.
apply, also 는 객체를 리턴합니다.
let, run, with 는 람다 결과를 리턴합니다.
<참고자료>
apply, with, let, also, run 은 언제 사용하는가?
'안드로이드' 카테고리의 다른 글
[Android, OOM] 메모리릭과 OOM이란? (2) | 2019.03.23 |
---|---|
[Android, ANR] Android Not Responding 는 무엇인가? (0) | 2019.03.23 |
[Android, Dagger2] ContributesAndroidInjector 사용해보기 (2) | 2019.03.17 |
[Android, Double Scroll] 이중 스크롤 어떻게 구성하면 좋을까? (6) | 2019.03.08 |
[Android, TargetVersion 28] TargetVersion 28 에 따른 조치 사항 (2) | 2019.03.06 |