코틀린 강좌 #14 스코프 함수

Kotlin/기본 문법 · 2020. 12. 19. 13:32

테크과학! DiMo

 

테크과학! DiMo

개발자가 얘기하는 생활 속 IT기술에 대한 과학! 여러분이 몰랐던, 혹은 정확히 알지 못했던 IT 테크놀러지를 파드립니다! 좋은 영상을 위한 채널 후원, 투네이션을 통해서 해주세요! 후원링크 htt

www.youtube.com

 

 

개발 환경: play.kotlinlang.org


람다함수의 특별한 케이스

 

1.람다함수도 여러 구문의 사용이 가능

 

val c:(String)-> Unit = {str -> 
    println("$str 람다함수") 
    println("여러 구문") 
    println("사용 가능") 
}

val cal:(Int, Int)-> Int = {a, b ->
    println(a)
    println(b)
    a+b // 마지막 구문인 a+b의 값을 Int로 반환
}

 

2. 람다함수에 파라미터가 없다면, 실행할 구문만 나열하면 된다.

 

val a:()->Unit = {println("파라미터가 없어도 됨")}

 

3. 파라미터가 하나 뿐이라면 it 사용

 

val c:(String) -> Unit = {println("$it 람다함수")}

 

스코프 함수


함수형 언어의 특징을 좀 더 편리하게 사용할 수 있도록 기본 제공하는 함수

 

 

스코프 함수에는

apply run with also let

 

 


apply : 인스턴스를 생성한 후 변수에 담기 전에 '초기화 과정'을 수행할 때 많이 쓰임


apply와 같은 스코프 함수를 사용하면 'main' 함수와 '별도의 scope'에서 인스턴스의 변수와 함수를 조작하므로 코드

 

가 깔끔해진다는 장점이 있다. 

 



run : apply처럼 run 스코프 안에서 참조연산자를 사용하지 않아도 된다는 점은 같지만

 

일반 람다함수처럼 인스턴스 대신 마지막 구문에 결괏값을 반환한다는 차이. 따라서 이미 인스턴스가 만들어진 후에 


인스터의 함수나 속성을 scope 내에서 사용해야 할 때 유용하다.

 

 


with: run과 '동일한 기능'을 가지지만 단지 인스턴스를 참조 연산자 대신 파라미터로 받는다는 차이뿐.
ex) a.run {...}   vs   with(a) {...}

 

 

fun main() {   
    // apply는 인스턴스 자신을 다시 반환
  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
    }
}

Output:
상품명 [초특가]디모의 코틀린, 가격: 8000원

 

also let :

처리가 끝나면 인스턴스를 반환 : apply/also

처리가 끝나면 최종 값을 반환  : run/let

 

 


다만 한가지 공통적인 '차이점'이 존재:

 


apply와 run이 참조 연산자 없이 인스턴스의 변수와 함수를 사용할 수 있었다면


also/let은 마치 파라미터로 인스턴스를 넘긴 것처럼 it을 사용해서 인스턴스를 사용할 수 있다.

 


파라미터를 통해서 인스턴스를 사용하는 과정을 거치는 이유:


같은 이름의 변수나 함수가 scope 바깥에 중복되어 있는 경우에 혼란을 방지하기 위해서

fun main() {
    var price = 5000 
    
    
    // apply는 인스턴스 자신을 다시 반환
    var a = Book("디모의 코틀린", 10000).apply {
        name = "[초특가]" + name
        discount()
    }
    a.run {
        println("상품명 ${name}, 가격: ${price}원") 
        // run 함수는 인스턴스 내의 price 속성보다 run이 속해있는 'main'ㅎ
        // 함수의 price 변수를 우선시해서 5000이 출력
    }
    a.let {
        println("상품명 ${it.name}, 가격: ${it.price}원")
        // main의 price 변수가 아닌 객체의 price를 사용한다.
        // apply역시 같은 상황일 경우 'also'를 사용하여 대체 할 수 있다.
    }
}

class Book(var name: String, var price: Int) {    
    fun discount() {
        price -= 2000
    }
}

Output:
상품명 [초특가]디모의 코틀린, 가격: 5000원
상품명 [초특가]디모의 코틀린, 가격: 8000원