클로저와 람다
개발이야기/함수형 프로그래밍2016. 7. 28. 22:28
자바스크립트를 사용하다보면 종종 클로저를 사용할 때가 있습니다. 아래와 같이 말이죠.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | function Vo() { var data; return { getData : function() { return data; }, setData : function(value) { data = value; } } } var closure = Vo(); closure.setData('Hello world'); console.log(closure.getData()); // Hello world | cs |
클로저의 구조를 보게되면 함수 안에 내부함수가 존재하며, 이 내부함수는 인스턴스같이 외부로 넘겨지기도 하고 비지역변수를 자유롭게 변경이 가능합니다.
람다나 익명클래스 역시도 저 동작과 비슷한 작업을 수행할 수 있습니다.
함수를 인수로 넘기는 것이 가능하며, 메소드 내부에 함수를 선언할 수 있습니다.
(아래 예제는 메소드 내부에 람다를 표현했고, 외부변수 x를 변경하였습니다.)
1 2 3 4 5 6 7 8 9 | private int x = 0; public void func(){ int data = 0; IntConsumer setData = (int a) -> x = a; setData.accept(5); } | cs |
"JAVA 8 IN ACTION" 에서는 이러한 점 때문에 람다가 클로저의 정의에 부합하는가에 대해서 다루고 있습니다.
결론부터 말하면, 서로 비슷한 일을 하고는 있지만 람다의 경우 선언된 지역변수의 데이터를 변경할 수 없습니다.
지역변수가 람다 내부에서 사용되려면 final 한 상태이어야 합니다. 혹은 final과 같은 동작을 하거나 말이죠 ㅡㅡ^
(아래 예제는 람다 표현식에서 지역변수 data를 변경하려 하지만, 이 것은 문법 오류라고 체크하게 됩니다.)
1 2 3 4 5 6 7 | public void func(){ int data = 0; // 문법 오류 IntConsumer setData = (int a) -> data = a; setData.accept(5); } | cs |
위와 같은 이유는 지역 변수 값의 경우 스택에 존재하며, 해당 메소드의 스레드 생명주기와 동일하게 종료되어야 합니다.
이것이 보장되지 않는다면 람다 내부 블럭이 실행 시, 안전하지 않은 동작이 수행되겠죠.
(멤버 변수의 경우 힙에 있으므로, 람다에 대해 특별한 제약이 없습니다.)
|
반응형
'개발이야기 > 함수형 프로그래밍' 카테고리의 다른 글
메서드 레퍼런스 (0) | 2016.08.01 |
---|---|
람다의 실제 형식 (0) | 2016.07.28 |
원시타입을 위한 함수형 인터페이스 (0) | 2016.07.28 |
JAVA8 에 정의된 함수형 인터페이스 (0) | 2016.07.28 |
함수형 인터페이스 (0) | 2016.07.27 |