연습장/이론

Kotlin_ 4-2-1. 스코프 함수

아이른 2024. 2. 22. 16:06

스코프함수(Scope function)
: 함수형 언어의 특징을 좀 더 편리하게 제공할 수 있도록 기본 제공하는 함수들
: 클래스에서 생성한 인스턴스를 스코프 함수에 전달하면, 인스턴스의 속성이나 함수를 스코프함수에 내에서 객체의 이름을 통해 일일히 참조할 필요 없이 객체를 접근하고 핸들링 할 수 있는 장점을 가짐

- 코틀린이 제공하는 스코프 함수
: applt, run, let, also, with



- apply
a.apply{
    //초기화 코드
}
: 객체 초기화 시 사용되며, 수신 객체(it 대신 this 사용)의 함수 또는 속성을 호출. apply는 객체 자체를 반환.

fun main(){
    var a = Book("만화책", 10000)
}
class Book(name:String, price:Int){
    fun discount(){
        price -= 2000
    }
}

만화책 앞에 '[초특가]'를 붙이고 싶을 때?

변수(a)를 통해 참조연산자를 사용하여 속성과 함수를 사용 apply 사용
fun main(){
    var a = Book("만화책", 10000)
    a.name = "[초특가]"+ a.name
    a.discount()
    println("상품명:${a.name}, 가격:${a.price}원")
}

class Book(var name:String, var price:Int){
    fun discount(){
        price -= 2000
    }
}
fun main(){
    var a = Book("만화책", 10000).apply{
        name = "[초특가]"+ name
        discount()
    }
    println("상품명:${a.name}, 가격:${a.price}원")
}

class Book(var name:String, var price:Int){
    fun discount(){
        price -= 2000
    }
}
<print>
상품명: [초특가]만화책, 가격:8000원
<print>
상품명: [초특가]만화책, 가격:8000원


: apply 함수 내의 모든 명령이 수행된 후 적용되어, 새로 생성된 인스턴스를 변수(a)에 바로 넣어줄 수 있음


- run
a.run {
  // 계산 코드
  return 마지막 결과값
}
: apply처럼 run 스코프 안에서 참조연산자를 사용하지 않아도 된다는 점은 같지만 인스턴스 대신 마지막 결과 값을 반환한다는 차이가 있음
: 이미 만들어진 인스턴스의 값 혹은 그를 이용한 특정 계산 결과를 필요로 하는 경우 사용

fun main(){
    var a = Book("만화책", 10000).apply{
        name = "[초특가]"+ name
        discount()
    }
    a.run{
        println("상품명:${a.name}, 가격:${a.price}원")
    }
}

class Book(var name:String, var price:Int){
    fun discount(){
        price -= 2000
    }
}
fun main(){
    var a = Book("만화책", 10000).apply{
        name = "[초특가]"+ name
        discount()
    }
    var bookCost = a.run{
        println("상품명:${a.name}, 가격:${a.price}원")
        price + 2000
    }
    println("원가는 ${bookCost}원 입니다")
}

class Book(var name:String, var price:Int){
    fun discount(){
        price -= 2000
    }
}
<print>
상품명: [초특가]만화책, 가격:8000원
//마지막 결과 값 : apply 구문 반환
<print>
상품명: [초특가]만화책, 가격:8000원
원가는 10000원 입니다
//마지막 결과 값 : price +2000 반환

- with
: run과 유사. 단지, 인스턴스를 참조연산자 대신 패러미터로 받는다의 차이가 있음

a.run{..} with(a){..}

- also, let

생성된 인스턴스를 반환 최종 실행 결과값을 반환  
apply run → 인스턴스의 변수와 함수를 사용
also let → it을 통해서 인스턴스를 사용

①③②④⑤

fun main(){
  ①var price = 5000
  ②var a = Book("만화책", 10000).apply{
        name = "[초특가]"+ name
        discount()
    }
    a.run{
        println("상품명:${name}, 가격:${price}원")
    }
}

class Book(var name:String, var price:Int){
    fun discount(){
        price -= 2000
    }
}
var price = 5000 를 추가했을 때, run?
① > ② 
: main() 스코프 내에 인스턴스 프로퍼터와 이름이 같은 변수가 있기 때문에 run함수가 인스턴스 내의 price 속성보다 run이 속해있는 main()의 price를 우선시하여 출력함을 볼 수 있음
<print>
상품명: [초특가]만화책, 가격:5000원
fun main(){
    var price = 5000
    var a = Book("만화책", 10000).apply{
        name = "[초특가]"+ name
        discount()
    }
    a.run{
        println("상품명:${name}, 가격:${price}원")
    }
    a.let{
        println("상품명:${it.name}, 가격:${it.price}원")
    }
}

class Book(var name:String, var price:Int){
    fun discount(){
        price -= 2000
    }
}
→ 이럴때, it 키워드 사용!
: 같은 이름의 변수나 함수가 scope바깥에 중복되어 있는 경우에 혼란을 방지
: it 키워드에 참조연산자를 통해 프로퍼티 및 함수에 접근
<print>
상품명: [초특가]만화책, 가격:5000원
상품명: [초특가]만화책, 가격:8000원