728x90
with 함수
수신 객체를 명시하지 않고 람다의 본문 안에서 다른 객체의 메서드를 호출할 수 있게 하는 람다를 수신 객체 지정 람다라 부르는데, with는 수신 객체 지정 람다를 활용한다.
어떤 객체의 이름을 반복하지 않고도 그 객체에 대해 다양한 연산을 수행할 수 있다(코틀린에서는 with라는 라이브러리 함수를 제공한다)
fun main(args: Array<String>) {
println(alphabet())
}
fun alphabet(): String{
val result = StringBuilder()
for (letter in 'A'..'Z'){
result.append(letter)
}
result.append("\nNow I know the alphabet!")
return result.toString()
}
- result에 대해 다른 여러 메서드를 호출하면서 매번 result를 반복 사용했다.
fun main(args: Array<String>) {
println(alphabet())
}
fun alphabet(): String{
val stringBuilder = StringBuilder()
return with(stringBuilder){//메서드를 호출하려는 수신객체를 지정
for (letter in 'A'..'Z'){
this.append(letter)//this 를 명시해서 앞에서 지정한 수신객체의 메서드를 호출
}
append("\nNow I know the alphabet!") //this 생략 가능
this.toString()//람다에서 값 반호나
}
}
- with의 첫 번째 파라미터는 stringBuilder이고, 두 번째 파라미터는 람다이다.
- 람다를 괄호 밖으로 빼내는 관례를 사용함에 따라 전체 함수 호출이 언어가 제공하는 특별한 구문처럼 보인다.
- with함수는 첫 번째 인자로 받은 객체를 두 번째 인자로 받은 람다의 수신 객체로 만든다.
- 인자로 받은 람다 본문에서는 this를 사용해 수신 객체에 접근할 수 있다.
- this와. 을 사용하지 않고 프로퍼티나 메서드 이름만 사용해도 수신 객체의 멤버에 접근할 수 있다.
fun main(args: Array<String>) {
println(alphabet())
}
fun alphabet(): String{
return with(StringBuilder()){
for (letter in 'A'..'Z'){
append(letter)
}
append("\nNow I know the alphabet!")
toString()
}
}
- 불필요한 stringBuilder 변수를 없애 alphabet 함수가 식의 결과를 바로 반환하게 한다.
- 식을 본문으로 하는 함수로 표현할 수 있다
- StringBuilder의 인스턴스를 만들고 즉시 with에게 인자로 넘겨 람다 안에서 this를 사용해 그 인스턴스를 참조한다.
TIP : 메서드 이름 충돌
만약 with에게 넘긴 객체의 클래스와 with에서 사용하는 코드가 들어있는 클래스 안에 이름이 같은 메서드가 있다면 어떻게 될까?
this 참조 앞에 레이블을 붙이면 호출하고 싶은 메서드를 명확하게 정할 수 있다.
apply 함수
with와 흡사하지만, 차이는 항상 자신에게 전달된 객체를 반환한다는 것이다.
fun main(args: Array<String>) {
println(alphabet())
}
fun alphabet() = StringBuilder().apply {
for (letter in 'A'..'Z') {
append(letter)
}
append("\nNow I know the alphabet!")
}.toString()
- apply는 확장함수로 정의되어 있다.
- apply의 수신 객체 가수 신 객체가 전달받은 람다의 수신 객체가 된다.
- 객체의 인스턴스를 만들면서 즉시 프로퍼티중 일부를 초기화해야 되는 경우 사용하기 유용하다.
- 자바에서는 보통 Builder 객체가 이런 역할을 담당하며, 코틀린에서는 라이브러리의 특별한 지원 없이도 클래스의 인스턴스에 대해 apply를 활용할 수 있다
fun createViewWithCustomAttributes(context: Context){
TextView(context).apply{
text = "Sample Text"
textSize = 20.0
setPadding(10, 0, 0, 0)
}
}
- apply 함수를 사용하면 함수의 본문에 간결한 식을 사용할 수 있다.
- 새로운 TextView인스턴스를 만들고 즉시 인스턴스를 apply에 넘긴다.
- apply에 전달된 람다 안에서는 TextView가 수신 객체가 된다.
- 원하는 대로 TextView의 메서드를 호출하거나 프로퍼티를 설정할 수 있다.
- 람다를 실행하고 나면 apply는 람다에 의해 초기화된 TextView인스턴스를 반환한다.
fun alphabet() = buildString {
for (letter in 'A'..'Z') {
append(letter)
}
append("\nNow I know the alphabet!")
}
- 표준 라이브러리의 buildString을 사용하면 더 단순화할 수 있다.
- buildString은 StringBuilder객체를 만드는 일과 toString을 호출해 주는 일을 알아서 해준다.
- buildString의 인자는 수신 객체 지정 람다며, 수신 객체는 항상 StringBuilder가 된다.
728x90
'KotlinInAction > 람다로 프로그래밍' 카테고리의 다른 글
| 자바 함수형 인터페이스 활용 (0) | 2022.08.03 |
|---|---|
| 지연 계산 컬렉션 연산 (0) | 2022.08.02 |
| 컬렉션 함수형 API (0) | 2022.08.01 |
| 람다 식과 멤버 참조 (0) | 2022.07.31 |