스택은 LIFO의 순서로 데이터를 저장하고 반출하는 데이터 구조입니다.
컴퓨터 공학을 살짝만 맛보더라도 알 수 있는 내용입니다.
LIFO 말고도 스택이 가지는 특성이 있는데, 바로 저장하는 데이터의 사이즈를 확실하게 알아야 저장할 수 있다는 것입니다.
스택에 저장되는 데이터는 고정된 사이즈이어야 합니다. 그 이유는 스택에 데이터가 저장될 때 연속된 메모리 주소에 저장이 되기 때문입니다.
즉, 데이터가 저장되어있는 공간이 연속되어있으므로 전체 데이터에 접근하는 것이 쉽고 빠릅니다.
힙은 수영장이나 엘리베이터 같은 장소입니다. 엘리베이터 문이 열릴때마다 빈 공간을 찾아가서 서듯이 데이터또한 힙 내부의 빈공간에 놓여지게 됩니다. 이러한 특성으로 인해 데이터의 사이즈가 동적으로 변해도 괜찮습니다.
사이즈가 정해지지 않다는 이야기는 특정 공간에 연속적인 메모리 주소를 포함하고 있지 않다는 뜻이기 때문에 데이터에 접근하는 것이 스택보다 느립니다.
방금 이야기한 스택과 힙의 특성을 알고있는 것이 아래에서 설명할 포인터를 공부할 때 얼마나 도움이 될지 한번 몸소 느껴보시기 바랍니다.
C언어를 공부해보신 분들이라면 아시겠지만 포인터는 메모리의 주소를 가리킬 때 사용하는 개념입니다.
러스트에서는 reference라는 이름으로 포인터가 사용됩니다. 이 reference가 어떤 주소를 가르키냐 하면 어떤 값의 메모리 주소를 가르킵니다.
여기서 러스트만의 특징이 드러납니다.
여기서 레퍼런스는 러스트에서 존재하는 포인터의 종류 중 한가지인데요, 그 중 레퍼런스를 사용한다는 의미는 값을 borrow 한다는 뜻입니다.
새로운 단어가 등장했어요. 값을 borrow하다.
네, 러스트에서는 소유권이라는 개념이 있어요.
값을 borrow 하는 것은 소유권을 가져오지는 않는다는 의미에요.
그 반대 의미는 소유권을 가져오는 것이고 이걸 러스트에서는 owned 라고 말해요.
let chocolate = 300;
let my_dream = &chocolate;
코드에서 my_dream은 chocolate의 reference에요.
앞서 말한 borrow와 접목시켜서 이야기해볼게요.
300을 borrow한 것은 my_dream이에요. 그리고 my_dream은 레퍼런스이자 포인터에요. borrow만 했기 때문에 300을 owned 하지는 않아요.
300을 owned 한 것은 my_dream이 아니라 chocolate에요.
borrow는 한 문장으로 설명해서
데이터의 소유권을 갖지 않고도 해당 값을 참조할 수 있는 개념이에요.
my_dream은 300의 메모리 주소를 가르키고 있어요.
소유권을 가지지는 않지만 300의 값을 사용할 수는 있게 된 것이죠.
let a = 5;
let b = &a;
아래에서 b
는 a
의 레퍼런스에요. 그리고 5 라는 데이터를 borrow했어요.
비유가 너무 좋네요!