[Kotlin] 수신 객체 지정 람다 : with / apply / let / run / takeif / also
수신 객체 지정 람다
with : prefix없이 접근하고 싶을 때
``kt with``는 원래 파라미터가 2개인 함수다. 그러나 두 번째 인자인 람다를 밖으로 빼서 원래 언어가 지원하는 구문인 것 처럼 사용할 수 있다. 보기 깔끔해진다.
``kt with``의 람다 내에서는 전달된 객체에 prefix없이 접근할 수 있다.
```kt
fun alphabet(): String {
val stringBuilder = StringBuilder()
return with(stringBuilder) {
for (letter in 'A'..'Z') {
this.append(letter)
append("!") // this 생략 가능
}
this@OuterClass.somFunc() // 바깥쪽 클래스 멤버 접근
this.toString() // return
}
}
```
또는 이렇게 리팩토링 할 수 있다.
```kt
fun alphabet() = with(StringBuilder()) {
for (letter in 'A'..'Z') {
append(letter)
}
toString()
}
```
내부에서 널체크를 수행해주어야 한다는 단점이 있음. 이런 경우 ``kt let``을 고려한다.
apply : 객체를 만들면서 인스턴스를 초기화하고 싶을 때
``kt apply``함수는 ``kt with``와 거의 비슷한데, 확장 함수로 정의되어 있으며 자신에게 전달된 객체를 리턴한다는 차이점이 있다.
위 함수를 ``kt apply``를 이용해 리팩토링하면 다음과 같다.
```kt
fun alphabet() = StringBuilder().apply {
for (letter in 'A'..'Z') {
append(letter)
}
}.toString()
```
``kt apply``함수는 객체의 인스턴스를 만들면서 즉시 프로퍼티 중 일부를 초기화해야 할 때 유용하다. ``kt apply`` 내에서 호출하는 메소드나 프로퍼티는 수신 객체의 메소드나 프로퍼티를 의미한다.
```kt
fun createViewWithCustomAttributes(context: Context) =
TextView(context).apply {
text = "Sample"
textSize = 20.0
setPadding(10, 0, 0, 0)
}
```
위 코드를 풀어 쓰면 이렇게 된다.
```kt
fun createViewWithCustomAttributes(context: Context) {
val t = TextView(context)
t.text = "Sample"
t.textSize = 20.0
t.setPadding(10, 0, 0, 0)
return t
}
```
let : 널이 될 수 있는 타입 인자로 넘기기
run 활용
takeif 활용
run let with apply also의 정의
```kt
inline fun <T, R> T.run(block: T.() -> R): R = block()
inline fun <T, R> T.let(block: (T) -> R): R = block(this)
inline fun <T, R> T.with(receiver: T, block: T.() -> R): R = receiver.block()
inline fun <T> T.apply(block: T.() -> Unit): T {
block()
return this
}
inline fun <T> T.also(block: (T) -> Unit): T {
block(this)
return this
}
use { }는 open하는 자원에 연결 시 close()를 자동으로 호출해줌
try-with-resources 에 대응한다고 보면 된다.
```
runCatching
try-catch-finally 대신 runCatching 도 사용 가능함. catch문 결과를 반환해주기 때문에 indent depth를 줄일 수 있음.
```kt
runCatching {
get()
}.fold(
onSuccess = { onSuccess(it) },
onFailure = { onFailure(it) }
).also {
finally()
}
```
'Java Stack > Kotlin' 카테고리의 다른 글
[Kotlin] 타입 시스템 (Any, Unit, Nothing) (0) | 2017.12.06 |
---|---|
[Kotlin] Nullability 관련 연산자 (0) | 2017.12.06 |
[Kotlin] 함수형 인터페이스(SAM)에 람다 사용하기 (2) | 2017.12.05 |
[Kotlin] stream API / 시퀀스(Sequence) (0) | 2017.12.04 |
[Kotlin] 람다(lambda), 변수 포획과 클로저, 멤버 참조 (0) | 2017.12.04 |