이름없이 실행이 가능한 함수를 람다식이라고 한다.
언어별로 람다식이 어떻게 다른지 정리해 보려고 한다.
자바
형식은 다음과 같다.
(매개변수, ...) -> { 실행코드 ... }
// 일단 인터페이스 정의가 필요하다.
interface Adder {
public int add(int a, int b);
}
// 람다를 인자로 사용하는 함수 정의
public void add(int a, int b, Adder adder) {
int value = adder.add(a, b);
}
// 람다를 인자로 사용하는 함수 호출
add(10, 20, (a, b) -> {
return a + b;
}
// 람다식을 함수포인터처럼 정의
Adder adder = (a, b) -> (a+b);
// 정의한 람다함수식 호출
adder(10, 20);
코틀린
// 익명함수
val adder = fun(a, b) { return a + b; }
println(adder(10, 20));
val adder: (Int, Int) -> Int = { a, b -> a + b }
println(adder(10, 20));
val hello: (String) -> String { "Hello $it" }
val res = hello("Samse")
// 하나의 메서드만 제공하는 인터페이스의 경우 다음예와 같이 코드를 간결하게 작성할수 있다.
fun setOnClickListener(listener: (View)->Unit)
button.setOnClickListener({ view -> doSomething() })
button.setOnClickListener() { doSimething() }
button.setOnClickListener { doSomething() }
ObjC
블록이 람다에 해당한다.
^코드로 블럭을 구분한다.
블럭코드 정의하여 사용하기
int (^adder)(int, int) = ^(int a, int b) { return a + b; };
adder(10, 20);
블럭코드 타입을 정의하여 인자로 사용하기
typedef int (^adder) (int a, int b)
- (void)add:(int)a value:(int)b adder:(adder)adder {
int value = adder(a, b);
NSLog(@"value : %d", value);
}
[self add:10 value:20 adder:^(a, b) -> {
return a + b;
}];
Swift
클로저가 블록에 대응되며 좀더 고급스럽다.
일급객체로서 인자로 전달할수 있고 변수/상수가 될수 있으며 함수의 반환값으로도 사용가능하다. 즉 함수를 반환하여 함수형프로그래밍이 가능하다.
{ (매개 변수) -> 반환타입 in
구현 코드 ...
}
매개변수 없을 때 in 삭제 가능
let action = UIAlertAction(title: String?, style: UIAlertActionStyle, handler ((UIAlertAction) -> Void)?)
let action = UIAlertAction(title: "OK", style: .default) {
(action) in
...
}
매개변수로 넘기는 경우의 예
func sorted(by areInIncreasingOrder: (E, E) -> Bool) -> [E]
func reverse(a: Int, b: Int) -> Bool {
return a > b
}
let values: [Int] = [ 1, 2, 3, 4, 5 ];
let reversed: [Int] = values.sorted(by: reverse)
let reversed: [Int] = values.sorted(by: { (a: Int, b: Int)-> Bool in
return a> b
})
클로저가 매개변수가 한개이거나 맨뒤에 있는 경우 좀더 코드를 생략이 가능하다.
let reversed3: [Int] = values.sorted() { (a: Int, b: Int)-> Bool in return a > b }
let reversed4: [Int] = values.sorted { (a: Int, b: Int)-> Bool in return a > b } // 소괄호 삭제
let reversed5: [Int] = values.sorted { (a, b) in return a > b } // 타입삭제
let reversed6: [Int] = values.sorted { return $0 > $1 } // 인덱스 사용