[Kotlin][학습노트] 람다식

tora·2021년 7월 11일

함수형 프로그래밍과 람다식

  • 함수형 프로그래밍에서는,
    함수의 연쇄작용으로 프로그램을 구조화하는 방식으로,
    -> 함수를 다른 함수의 인자 혹은 반환값에 넣어주는 고차함수 개념의 구조가 가능
    -> 함수를 변수나 자료구조에 저장하는 개념이 가능
  • 함수형 프로그래밍에서 람다식은,
    함수로직 자체를 변수로서 할당, 전달 가능하게 하는 함수이자 변수로 볼 수 있다.

람다식

  • 람다식의 선언 : (매개변수자료형1 , 2, ...) -> 반환자료형
  • 람다식의 할당 : {매개변수1, 2, ... -> 반환식}

1) 일반 변수에 람다식 할당

  • 자료형은 선언부분, 할당부분 중 하나에만 명시해도 가능
  • 표현식이 2줄 이상일 때 : 마지막 표현식이 반환됨
    val lamTest: (Int,Int) -> Int = {x: Int, y: Int -> 
        var a: Int = x * y
    	a + y
    	} // 마지막 표현식 a + y가 반환됨
    println(lamTest(2, 3))	//9
  • 매개변수가 없을 때 : 선언은 빈괄호식 (), 할당은 -> 전반부 없이
  • 반환 자료형이 없을 때 : 선언 시 Unit 표시
	//매개변수 x & 반환자료형 x
	var a1:() -> Unit = {println("test")}
	a1()    //test

2) 함수의 인자로 람다식 전달

  • 에 의한 호출 : 람다식 자체가 아닌 람다식을 호출하여 수행한 결과를 값으로 전달하는 방식
    -> 함수 선언 시 매개변수에 람다식의 반환자료형과 동일한 자료형이 선언되어 있음
  • 이름에 의한 호출 : 람다식 함수 자체를 전달하는 방식 (호출없이 이름만 전달)
    -> 함수 선언 시 매개변수에 람다식이 선언되어 있음
  • 다른 함수 참조에 의한 호출
    -> 람다식이 아닌 함수로 선언된 식은 이름으로만 호출 불가능
    -> 함수를 람다식처럼 전달하기 위해 :: 표시하여 전달 가능
  fun printTest1(a: Int) {
      println(a)
  }
  fun printTest2(a: (Int, Int) -> Int) {
      var ret = a(2, 3)
      println(ret)
  }
  fun lam2(a: Int, b: Int) = a + b + 4

  fun main() {

      val lam1: (Int, Int) -> Int = {a, b -> a + b + 4}

      //값에 의한 호출 
      printTest1(lam1(2, 3))	//9

      //이름에 의한 호출
      printTest2(lam1)	//9

      //printTest2(lam2)	//컴파일 에러 : Type mismatch: inferred type is Int but (Int, Int) -> Int was expected
      //다른 함수 참조에 의한 호출
      printTest2(::lam2)	//9
  }
  • 람다식이 매개변수로 표현된 함수의 호출 간략화
    -> 람다식이 함수의 마지막 매개변수인 경우 람다식을 괄호 밖으로 빼내서 호출 가능
    (끝부분에 람다식 매개변수가 여러개여도 마지막 식만 분리 가능!)
    -> 람다식이 유일한 매개변수인 경우 밖으로 빼낸 후 괄호 생략 가능
  fun lamt(a:Int, b: () -> String) {
      println(b())
  }
  fun lamt2(b: () -> String) {
      println(b())
  }

  fun main() {
      lamt(1, {"hi"})
      lamt(1){"hi"}	//람다식이 함수의 마지막 매개변수인 경우
      
      lamt2({"hi2"})	
      lamt2{"hi2"}	//람다식이 유일한 매개변수인 경우
  }

3) 람다식 표현의 간략화

  • 람다식의 매개변수가 한 개 일 때 :
    매개변수 ~ -> 부분을 생략 / it으로 지칭 가능
    (2개 이상일 때에는 생략 불가)
    var aa1: (String) -> String = {a -> "Hello$a"}
    
    // a -> 부분 생략 & it 지칭
    var aa2: (String) -> String = {"Hello$it"}
    println(aa1("!"))	//Hello!
    println(aa2("!"))	//Hello!
  • 미사용 매개변수가 존재할 경우 :
    언더바(_)로 변수명 지칭 생략
    var test: (Int, Int) -> Int = { a, _ -> 3 + a}
    println(test(1, 2))	//4

0개의 댓글