Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

closure에 대하여 설명해주세요. #29

Open
0Hooni opened this issue Jan 12, 2025 · 4 comments
Open

closure에 대하여 설명해주세요. #29

0Hooni opened this issue Jan 12, 2025 · 4 comments

Comments

@0Hooni
Copy link
Collaborator

0Hooni commented Jan 12, 2025

No description provided.

@hsw1920
Copy link
Owner

hsw1920 commented Jan 14, 2025

Q. 클로저에 대해서 설명해주세요.
A.
클로저는 코드를 중괄호로 묶어둔 코드 블록을 말하며, 주로 이름이 없는 익명 함수로 사용됩니다. 함수는 이름이 있는 클로저라고도 할 수 있습니다. 클로저의 중요한 특성은 바로 캡처 목록을 사용하여 외부의 상태를 참조하고, 이를 클로저가 실행될 때까지 유지할 수 있다는 점입니다. 이를 통해 외부 변수나 상수를 클로저가 자기 내부로 캡처한다고 표현합니다.

일반적으로 클로저는 { (캡처 목록) in (반환값) } 형태로 사용되며, 캡처 목록과 in을 생략하거나 $0, $1 등의 숫자 인덱스를 활용해 한 줄로 간결하게 표현할 수 있습니다. 예를 들어, 배열의 map이나 filter와 같이 클로저를 인자로 받는 함수에서 자주 활용됩니다.

또한, 클로저는 일급 객체로서 함수처럼 변수에 할당되거나 다른 함수에 전달, 반환될 수 있습니다. 이런 특성 덕분에 고차 함수나 비동기 작업에서 유용하게 사용됩니다.

답변 의도

  • 클로저의 캡처 변수, 일급 객체의 특성을 설명한다.

꼬리질문

Q. 탈출 클로저에 대해서 설명해주세요.
A.
함수의 실행이 종료된 이후에 실행되는 클로저를 escaping closure(탈출 클로저)라고 부릅니다.

탈출클로저는 외부 변수 혹은 상수에 값을 저장할 수 있는 큰 특징이 있습니다.

때문에 함수가 종료된 뒤 실행되는 시간이 오래걸리는 비동기 네트워크 작업들을 탈출 클로저 콜백 함수를 통해 주로 구현합니다. 이런 비동기 작업을 탈출 클로저가 아닌 non-escaping closure에서 수행한다면 응답이 수신되기 전에 클로저가 실행되는 문제가 발생하여 원하지 않는 방식으로 동작할 수 있습니다.

또한 탈출 클로저는 함수가 종료된 이후에도 실행을 보장하기 때문에 지속적으로 캡처 변수를 참조하여 self를 강한 참조하는 방식의 순환참조를 통해 메모리 누수 문제가 발생할 수 있기 때문에 주의해야 합니다.
답변 의도

  • non-escaping closure와의 차이점 설명
  • 탈출 클로저의 외부 변수, 상수 저장하는 특징
  • 탈출 클로저에서만 순환 참조 문제가 발생할 수 있는 이유

@youn9k
Copy link
Collaborator

youn9k commented Jan 14, 2025

클로저는 어떠한 기능을 하는 코드 블럭을 의미합니다.
코드레벨에선 중괄호를 통해 감싸진 코드 블럭을 말하며, 익명 함수라고도 불립니다.
이러한 클로저는 일급 객체로 변수에 할당될 수 있고 다른 함수의 파라미터로 전달도 가능합니다.

클로저는 스코프 내에서 외부 변수를 사용할 경우 캡쳐를 통해 외부 변수의 reference를 참조하는 방식으로 동작합니다.
이 때 주의해야할 점은 해당 외부 변수가 value 타입이더라도 참조 캡쳐(Reference Capture)하기 때문에, 클로저가 해당 변수를 사용하는 시점에 따라 클로저의 결과가 달라질 수 있음을 주의해야합니다.
만약 이러한 특성이 불편해 복사 캡쳐(Copy Capture)하려면 캡쳐 리스트를 사용할 수 있습니다.
클로저의 시작 부분에 [ ] 안에 복사하고 싶은 외부 변수명을 넣게 되면, 해당 변수는 클로저를 선언할 당시의 값으로 복사되어 캡쳐됩니다.

@0Hooni
Copy link
Collaborator Author

0Hooni commented Jan 14, 2025

🙋🏻 답변

클로저는 간단히 표현하자면 함수처럼 사용할 수 있는 코드 블록입니다. 함수와 유사하게 특정 기능을 하는 코드 블럭을 만들어 반복적인 기능 수행을 할 수 있게 해주지만, 함수와는 다르게 이름 없이 사용도 가능해서 익명함수라고도 불립니다.

또한 클로저는 일급 객체로 사용이 가능합니다. 함수의 파라미터로 전달해주거나 반환타입으로 사용할 수 있습니다. 이 때 함수의 파라미터로 전달해주는 클로저에 escaping 키워드를 붙여 사용도 가능한데요.

탈출클로저라고 불리는 이스케이핑 클로저는 주로 비동기 작업에서 많이 사용됩니다. 작업이 끝나면 클로저를 통해 결과를 전달해줄 수 있기 때문입니다.

클로저는 다양한 상황에서 활용이 되지만 사용시 주의해야 되는 부분도 존재합니다. 클로저는 외부의 값이나 참조를 할 때 캡처를 하게 되는데 이 때 기본적으로 강한 참조로 캡처를 하기 때문에 순환 참조 문제가 발생할 수 있습니다.

🏷️ 키워드

함수비교, 코드블록, 익명함수, 일급객체, 탈출클로저, 캡처, 순환참조

@Kiyoung-Kim-57
Copy link
Collaborator

클로저

보통 우리가 클로저라고 부르는 것은 Unnamed Closure로 익명함수를 뜻한다.
클로저는 일급객체로 변수, 상수에 할당하거나 함수의 인자, 반환값으로 쓸 수 있다.
일급객체인 클로저를 활용해 고차함수를 구현할 수 있고 고차함수는 함수형 프로그래밍 구현에 적합하다.

클로저의 참조 캡쳐

클로저는 기본적으로 참조 타입으로 힙에 값을 저장한다. 이 때 필요한 인자들을 '캡쳐'해서 가져가게 되는데 기본적인 캡쳐는 참조 캡쳐이다. 클로저가 참조된 캡쳐 값을 수정하면 외부의 원본에도 영향을 주게 된다.

클로저의 값 캡쳐(캡쳐리스트)

참조 캡쳐말고 값 캡쳐를 위해 사용하는 것이 '캡쳐리스트'이다.
캡쳐리스트를 간단하게 설명하면 클로저가 힙에 저장될 때 가져갈 인자들을 상수로 복사하여 가져가는 리스트라고 생각하면 된다.
상수로 가져가서 복사하기 때문에 값 타입을 캡쳐하면 깊은 복사가 일어나 별개의 데이터로 사용할 수 있다.
하지만 참조 타입을 캡쳐하면 참조 주소를 복사하는 얕은 복사가 일어난다. 이 경우 기본 참조 캡쳐와 같아 보일 수 있다.
기본 참조 캡쳐는 강한 캡쳐를 하게 되는데 이는 순환 참조의 위험성을 내포하고 있다. 하지만 캡쳐리스트를 활용하면 이를 방지할 수 있다.
캡쳐리스트를 통해 참조 타입을 캡쳐할 때 weak, unowned 키워드를 사용하면 참조 카운트를 증가시키지 않아 캡쳐 시에 순환참조를 방지할 수 있다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants