스코프 함수
함수형 언어의 특징을 좀 더 편리하게 사용할 수 있도록 기본 제공하는 함수이다.
인스턴스를 스코프 함수 내에서 활용하게 되면 인스턴스 내의 속성이나 함수를 깔끔하게 쓸 수 있다. (Framework와 유사기능)
스코프 함수에는
- apply
- run
- with
- also
- let
- ....
과 같이 다양한 함수가 있다. 예시 코드로 하나씩 살펴보자.
1) apply
: 인스턴스를 생성 한 후 변수에 담기 전 초기화 과정을 수행할 때 많이 쓰인다.
보통 코틀린에서 클래스 및 클래스 객체 및 함수를 활용할 경우에는 다음과 같이 쓰인다.
public inline fun <T> T.apply(block: T.() -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
return this
}
class Coffee(var name: String, var price: Int) {
fun discount() {
price -= 500
}
}
var coffee = Coffee("아메리카노", 2500)
coffee.name = "[포장할인]" + coffee.price
coffee.discount()
// java 버젼
@Getter
class Coffee {
private String name;
private int price;
public Coffee(String name, int price) {
this.name = name;
this.price = price;
return new Coffee(this.name, this.price);
}
public discount() {
this.price -= 500;
}
}
Coffee coffee = new Coffee("아메리카노", 2500)
String coffee_name = "[포장할인]" + coffee.getName();
coffee.discount()
여기서 [포장할인] 서두를 붙이기 위해서는 속성과 함수를 이용해야 한다. apply는 참조 연산자 없이 활용할 수 있다. 왜냐하면 apply는 인스턴스 자신을 반환하기 때문이다.
다음과 같이 활용할 수 있다.
coffee = Coffee("아메리카노", 2500).apply {
name = "[포장할인]$name"
discount()
}
// java 버전에서는 apply 역할을 하는 메소드를 작성해야 한다.
public Coffee apply() {
String name = "[포장할인]" + this.name;
discount();
return new Cofffe(name, this.price);
}
2) run
: 이미 인스턴스가 만들어진 후에 인스턴스의 함수나 속성 scope 내에서 사용했을 때 유용하다. -> 예를 들어 자바 생성자 호출 후 해당 생성자에 관한 메소드나 변수값을 핸들링 할 때 유용한다.
@kotlin.internal.InlineOnly
public inline fun <T, R> T.run(block: T.() -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block()
}
coffee.run {
println("상품명: ${name}, 가격: ${price}원")
this.name = name.replace("아메리카노", "피자 토스트 세트")
price = 4500
}
coffee.run {
println("상품명: ${name}, 가격: ${price}원")
}
// 결과
// 상품명: [포장할인]아메리카노, 가격: 2000원
// 상품명: [포장할인]피자 토스트 세트, 가격: 4500원
// java 버전에서는 run 역할을 하는 메소드를 작성해야 한다.
public Coffee apply() {
String name = "[포장할인]" + this.name;
discount();
return new Cofffe(name, this.price);
}
public Coffee run() {
println("상품명 : " + this.name +", 가격: "+ this.price)
String name = this.name.replace("아메리카노", "피자 토스트 세트");
this.price = 4500
return new Coffee(this.name, this.price);
}
public class main() {
Coffee coffee = new Coffee();
coffee = coffee.run()
println("상품명 : " + coffee.getName() +", 가격: "+ coffe.getPrice())
}
3) with
: run과 동일한 기능, 차이점은 인스턴스를 참조 연산자 대신 파라미터로 받는다.
with(coffee) {
println("상품명: ${name}, 가격: ${price}원")
}
// 결과
// 상품명: [포장할인]피자 토스트 세트, 가격: 4500원
//java 버전
public Coffee run(Coffee coffee) {
println("상품명 : " + coffee.getName() +", 가격: "+ coffe.getPrice())
}
4) also
: also를 활용하면 it을 통해서 인스턴스 표현 가능 및 인스턴스로 반환한다.
// also
public inline fun <T> T.also(
block: (T) -> Unit
): T
var vanillaCoffee = coffee.also {
it.name = it.name.replace("피자 토스트 세트", "바닐라 라떼")
"coffee also 실행" // 무시 됌
}
vanillaCoffee.run {
println("상품명: ${name}, 가격: ${price}원")
}
// 결과
// 상품명: [포장할인]햄치즈 토스트 세트, 가격: 4000원
인스턴스로 반환하므로 coffee.also에서 also 안의 String 인 "coffee also 실행" 하는 부분은 무시한다.
5) let
: let 또한 also와 같이 it을 통해서 인스턴스 표현이 가능하지만 인스턴스를 반환하는 것이 아닌 최종값을 반환한다.
// also
public inline fun <T, R> T.let(
block: (T) -> R
): R
var cafeLatte = coffee.let {
it.name = it.name.replace("피자 토스트 세트", "카페라떼")
it.price = 3000
"coffee also 실행 -> cafeLatte"
}
cafeLatte.run {
println("상품명: ${name}, 가격: ${price}원")
}
println(cafeLatte)
// 결과
// coffee let 실행 -> cafeLatte
왜냐하면 let은 최종값으로 반환하므로 Coffee 객체가 아닌 String으로 반환한다.
즉 "coffee let 실행 -> cafeLatte"로 반환된 것이다.
끝.
'개발 지식 > Kotlin' 카테고리의 다른 글
[Coroutine] Coroutine Basic (0) | 2022.08.23 |
---|---|
[Kotlin] Kotlin 기초 - 05 (문자열) (0) | 2022.08.21 |
[Kotlin] Kotlin 기초 - 03 (스코프 /고차 람다 함수) (0) | 2022.05.16 |
[Kotlin] Kotlin 기초 - 02 (클래스/인터페이스) (0) | 2022.04.27 |
[Kotlin] Kotlin 기초 -01 (0) | 2022.04.24 |
댓글