개발을 시작하시는 여러분, 정보가 너무 많고 배워야 할 것도 산더미라 어디서부터 시작해야 할지 막막하신가요? 내일배움캠프 수료생들이 4개월 동안 배운 엄선된 핵심 개념을 직접 정리해서 알려 드립니다. 공부하다 막히거나 헷갈리는 개념이 있다면 개념 콕으로 정리해보세요.
우리는 개발을 하며 종종 람다식 혹은 람다 함수라는 말을 듣게 된다. 정확히는 람다 표현식(Lambda Expression)이라고 부르는데 람다 표현식이란 대체 뭘 말하는 걸까? 차근차근 알아보자.
익명 함수
일반적으로 함수는 선언을 통해 정의하고, 해당 함수의 함수명을 통해 호출해 사용한다.
하지만 딱 한 번만 쓰는 함수를 매번 이런 식으로 정의해서 사용하게 된다면 어떻게 될까? 아마 코드에는 똑같은 이름의 함수가 수십 개가 생겨나게 될 것이다. 다행히 Kotlin을 포함한 대부분의 현대적인 고차언어 들에서는 함수를 정의하지 않고 사용하는 방법들이 존재한다. 익명 함수는 이처럼 함수를 정의 없이 사용하는 방법 중 하나다.
익명 함수는 말 그대로 이름이 없는 함수를 말한다. 일반적으로 계속해서 사용하는 함수의 경우 해당 함수의 함수명을 선언부에 입력해, 해당 함수의 함수명을 통해 호출해 사용이 가능하다. 하지만 익명 함수의 경우 함수명을 정의하지 않고 바로 실행하거나 변수, 혹은 다른 함수에 전달되는 매개변수로 사용된다.
fun sum(a: Int, b: Int): Int { return a + b }
기존의 함수가 위와 같이 이름과 매개변수, 반환값, 본문으로 구성되었다면, 익명 함수는 아래와 같이 함수명 없이 바로 선언된다.
fun(a: Int, b: Int): Int { return a + b } // 기본적인 익명 함수의 형태 // 익명 함수 뒤에 ()를 통해 매개변수를 전달하면 바로 실행된다. println(fun(a: Int, b: Int): Int { return a + b }(3, 4)) // 출력 : 7 // 변수에 할당해 함수를 호출하듯 사용하는 것도 가능하다. val sum = fun(a: Int, b: Int): Int { return a + b } println(sum(1, 2)) // 출력: 3 // 변수에 즉시 실행한 결과를 할당하는 것도 가능하다. val sumResult = fun(a: Int, b: Int): Int { return a + b }(10, 20) println(sumResult) // 출력: 30
익명 함수는 기존의 함수가 함수명(x, y) 형식으로 호출해 사용하듯 익명 함수의 뒤에 ()를 사용해 바로 사용이 가능하며, 변수에 할당해서 변수명(x, y)와 같은 방식으로도 사용할 수 있다.
함수 값
이처럼 현대의 언어들은 익명 함수를 변수에 할당하거나, 다른 함수에 매개변수로 전달할 수 있도록 설계되어 있는데, 사실 익명 함수뿐만 아니라 모든 함수는 이렇게 다른 함수에 인자로 전달되는 게 가능하다. 이를 함수값이라고 한다. 변수의 경우에는 이름이 중복되니 익명 함수를 할당할 수 있다.
쉽게 말해 1, “Hello”, 3.4f와 같은 고정된 타입의 값뿐만 아니라 전달 받은 두 값을 하나로 더해서 합을 반환과 같이 특정 동작(함수)을 값처럼 취급하는게 가능하다는 말이다. 보통 람다 표현식이나 익명 함수에 대한 정보를 찾다 보면 일급 객체라는 말을 많이 보게 되는데 간단하게 일급 객체의 특성을 살펴보면 다음과 같다.
- 변수에 할당 될 수 있다.
- 함수의 매개변수로 전달이 가능하다.
- 함수의 반환값으로도 사용할 수 있다.
- 프로그램 실행중에 동적으로 생성이 가능해야한다.
Int, Char, Float, Double, String과 같은 기본적인 데이터 타입이 일급 객체인데, 많은 언어들이 기본 데이터 타입 말고도 함수를 일급 객체로 취급하기 때문에 함수를 값처럼 취급하는 게 가능해진다.
람다 표현식(Lambda Expression)
그래서 결국 람다 표현식은 뭘 말하는 걸까? 람다 표현식은 앞서 알아본 익명 함수와 같이 정의와 함께 바로 함수를 실행시키는 함수 정의 방식 하나로, 익명 함수보다 훨씬 간단하게 사용할 수 있어 개발을 하며 수도 없이 사용하게 되는 함수 정의 방식이다. 람다 표현식은 간결함 때문에 보통 함수에 전달되는 매개변수나, 함수의 반환값으로 많이 사용된다.
익명 함수의 경우 함수 예약어(fun)와 매개변수를 명시하는 ()부분을 작성해야 했다면, 람다 함수는 코드 블록 안에 직접 매개변수를 명시하고 본문을 작성한다. 위에서 정의했던 익명 함수를 람다 표현식으로 작성하면 다음처럼 변형된다.
// 기존의 익명 함수 fun(a: Int, b: Int): Int { return a + b } //람다 표현식 {a: Int, b: Int -> a + b }
기호로 매개변수와 함수 본문이 분리된다. 람다 표현식에서는 return문을 사용하지 않으며, 마지막 라인의 결과값이 반환값으로 반환된다.
또한 매개변수가 하나일 경우 매개변수를 명시하지 않고 it으로 사용하는 게 가능하다.
{ a: Int -> a * 2 } { it * 2 }
람다 표현식을 사용하면 함수에 함수값을 전달해야 할 경우 보다 간결하게 전달이 가능해진다.
fun sumSum(numA: Int, NumB: Int, sum: (Int, Int) -> Int): Int { val result = sum(numA, numB) + sum(numA, numB) return result } println(sumSum(2, 4, { numA, numB -> numA + numB })) // 결과 : 12 // 람다표현식 안의 a, b는 매개변수의 타입이 (Int, Int) -> Int 이므로 자동으로 타입 추론
또한 Kotlin에서는 함수의 마지막 매개변수가 함수 타입이라면(함수값을 전달받아야 한다면) 람다 표현식의 블록{}을 괄호 () 밖으로 빼서 쓰는 게 가능한데, 이렇게 블록을 밖으로 빼고 보면 어딘가 익숙한 형태로 변하게 된다. 특히 매개변수가 1개뿐이라면 우리가 항상 사용하고 있는 함수와 비슷한 형태가 된다.
sunSum(2, 4, { numA, numB -> numA + numB }) sumSum(2, 4) { numA, numB -> numA + numB} // 두가지 모두 올바른 방법이다. list.forEach({ println(it) }) // 매개변수가 하나이기 때문에 생략 후 it으로 사용가능 list.forEach{ println(it) } // ()안에 들어갈 값이 없어서 생략
우리가 자주 사용하는 forEach라든지 filter같은 함수들도 내부적으로 함수값을 전달받아 동작하기 때문에 람다 표현식을 사용하는 위와 같은 형태가 되는 것이다.
우리는 알게 모르게 항상 람다 표현식을 사용하고 있었던 것이다! 람다? 이제 겁먹지 말라!
람다 표현식 메커니즘 이해
함수값과 익명 함수, 람다 표현식에 대해 이해하더라도 처음에는 함수값이란 게 어떤 식으로 동작되는지 와닿지 않아 헷갈리는 경우가 많다.
그래서 좀 더 함수값을 이해하기 편하도록 정리하며 마무리해 보자.
다음과 같은 코드에서 함수값을 전달받아 사용한다고 했을 때 흐름을 살펴보자.
val twoFour = sumSum(2, 4) { a, b -> a + b } fun sumSum(numA: Int, NumB: Int, sum: (Int, Int) -> Int): Int { val result = sum(numA, numB) + sum(numA, numB) return result }
sumSum 함수는 Int 타입의 값 두 개를 전달받아 sum으로 전달받은 람다를 실행한 후 반환된 값으로 계산한 결과를 return 한다. 복잡해 보이지만 그림으로 순서를 정리해 보면 좀 더 이해가 쉽다.
즉 함수 내부의 값을 전달받은 함수값에 전달해 밖에서 함수값의 내용을 실행, 결과를 가지고 다시 함수 내부 돌아와 나머지 동작을 수행하고 결과를 반환하는 거라고 생각하면 된다.
내일배움캠프는 개발에 필요한 핵심만 배웁니다
지금까지 꼭 필요한 개발 지식에 대해 알아보았습니다. 내일배움캠프에서는 전문가들이 선별한 핵심 개발 지식으로 개발 공부도, 취업도 보다 효율적으로 할 수 있는데요. 국내 유수의 IT기업 출신 튜터님들과 실습 위주의 독보적인 커리큘럼으로 개발자 취업을 체계적으로 준비해보세요. 내일배움캠프 4개월, 여러분 인생의 가장 큰 터닝 포인트입니다.
CREDIT
글 | 배영수 내일배움캠프 수료생
편집 | 정효재 팀스파르타 에디터
취업 준비, 어디서부터 시작해야 할지 모르겠다면?
🧐비전공자인데 IT 업계 취업할 수 있을까?
😟프로젝트 경험이 부족한데, 어떻게 준비해야 할까?
🥺IT 기업으로 이직하고 싶은데 뭐부터 시작해야 할까?
이런 고민을 하고 있다면, 내일배움캠프의 IT 취업 컨설팅을 받아보세요.
취업 코칭 전문가들이 여러분의 고민을 해결해 드립니다.
다음 링크에 이메일을 입력하시면 메일로 1:1 커리어 상담권과 취준 자료집을 보내드릴게요.
Share article