본문 바로가기

카테고리 없음

Why Closure can't mutate Value type?

closure 내부에서 value type 즉 struct, enum 값을 변경하려고 할 때 컴파일러는 빌드할 수 없다는 에러를 보여줍니다.
예전에는 그냥 class로 고치고 넘어갔던 문제였지만, 근본적으로 다시 돌아가서 "왜 변경할 수 없을 까"가 오늘의 주제입니다.
(뇌피셜이기 때문에 다른 생각을 갖은 분들은 댓글에 생각을 남겨주시면 감사하겠습니다.)

역으로 escaping closure가 어떤 상황을 만날 수 있는지 생각해보면, 클로저를 선언시킨 시점과 클로저를 실행시키는 시점이 전혀 다른 상황일 수 있습니다. 즉 Thread Safe한 상황이 아닐 수도 있다는 겁니다.
1. Value Type의 특징 중 하나인 Thread Safe를 지킬 수 없기 때문에 컴파일러 단에서 막은 거 같습니다.
2. Value Type을 캡처하면 복사 된 값을 변경하기 때문에, 캡쳐하는 의미가 사라집니다.

Thread에 대한 정의를 검색하던 중 의도치 않게 정답을 찾았습니다.
아래 사진은 Process 내부를 표현한 그림입니다.
Thread를 살펴보면 각각 다른 Stack 영역을 갖고 있는걸 확인할 수 있습니다.

Value Type 즉 struct는 저장될 때 원론적으론 Stack영역에 할당됩니다.
비동기적인 작업을 할때, 각기 다른 Thread가 해당 값을 변경할 수 없었던 이유는 Thread의 설계로 인해서 애당초에 불가능한 부분이였습니다.


--- 번외 ---
그렇다면 추가적으로 해당 에러문(closure 내부에서 변경할 수 없다는)이 개발자에게 어떤 의미로 다가올 수 있을까 라는 생각을 하게됐습니다.
closure 내부에서 capture하는 모든 객체는 class로 선언하는 방법보다는 closure 내부에서 캡쳐하는 값일수록 더 민감하게 관리를 해야겠다는 생각이 들었습니다. (새로운 스트림에서 값을 방출하는 방식으로 closure 내부에서 값을 변경하는 방식과 다르게 원하는 결과를 얻을 수 있습니다.)
해당 에러문은 오히려 개발자에게 현재 작성하는 코드가 위험할수도 있다는 메세지를 준다는 생각을 했습니다.