러스트 반나절 공부하고 느낀점
rust가 go와 비슷한 점이 많네요. C 계량형이라는 점에서요. rust는 C의 메모리 안정성, go는 C의 생산성을 업그레이드 한거니까요
기억력이 나쁜 탓에 학창시절에도 수학공부할때 수학공식은 외우지 않고 기본원리에서부터 문제해결을 도출해 온 스타일이고 그래서 go처럼 심플하면서도 경제적인 코드를 좋아하는데 rust도 반나절만 본것뿐이지만 코드가 경제적이라는 느낌이 드네요
heap 에서 memory leak, dangling point 등 문제 잡기 위해서 도입한 ownership take, borrow 그리고 scope, lifetime 이 개념상으로는 어려운 것은 아니지만
오키 누군가도 이야기 했듯이
이걸 멀티스레딩, 복잡한 데이터 구조 (트리, 그래프 등), 클로저, 또는 비동기 프로그래밍에서 적용하려면 상당히 골치 아플거다 이거죠?
그리고 최강의 성능을 위해서 gc없는 rust 쓰는건데 멀티스레딩, 비동기 안하면 또 그 장점이 많이 줄어드는거니까 결국 하려면 그것까지 익숙해지도록 해야 한다는거고
나
Rust 공부해보니까 c처럼 메모리 malloc, free가 필요없고 그냥 ownership 과 scope, lifetime 만 머리쓰면 자동 메모리 관리가 되는건데 이게 뭐가 어려워? 반자동도 아니고 그냥 자동인데
gemini
Rust를 공부하시면서 Ownership, Scope, Lifetime 개념만으로 자동 메모리 관리가 된다고 느끼셨다면, Rust의 핵심적인 강점을 잘 파악하신 겁니다! 실제로 Rust는 C처럼 수동으로 malloc이나 free를 호출할 필요가 없어서 메모리 관련 버그를 크게 줄여줍니다. 언뜻 보면 정말 편리하고 간단하게 느껴질 수 있습니다.
Rust의 자동 메모리 관리, 하지만 '반자동'의 측면
하지만 Rust의 메모리 관리가 '완전 자동'이라기보다는 '반자동'에 가깝다고 보는 시각도 있습니다. 그 이유는 다음과 같습니다.
* 컴파일러의 엄격함: Rust 컴파일러는 Ownership 규칙을 매우 엄격하게 적용합니다. 소유권 이전, 빌림 (불변/가변), 라이프타임 주석 등을 코드로 명시해야 하고, 이 규칙을 위반하면 컴파일조차 되지 않습니다. C나 C++에서 메모리 버그가 런타임에 발생하여 디버깅이 어려운 것과 달리, Rust는 컴파일 시점에 문제를 잡아내죠.
* 개발자의 '사고방식' 변화 요구: 이러한 엄격함은 개발자에게 메모리를 다루는 방식에 대한 새로운 사고방식을 요구합니다. 예를 들어:
* "누가 데이터를 소유하는가?": 모든 데이터에는 단 하나의 소유자만 있어야 합니다.
* "언제 데이터를 빌려줄 수 있는가?": 데이터를 빌려줄 때는 불변 참조(읽기 전용)이거나 가변 참조(쓰기 가능) 중 하나여야 하며, 가변 참조는 동시에 하나만 존재해야 합니다.
* "참조는 얼마나 오래 유효한가?": 빌려온 참조는 원본 데이터보다 오래 살 수 없습니다.
이런 규칙들을 자연스럽게 이해하고 코드에 적용하는 과정이 학습 곡선을 형성합니다. C/C++처럼 '내 맘대로' 메모리에 접근하다가는 컴파일러의 벽에 부딪히게 되죠.
* 복잡한 시나리오: 단순한 데이터 구조나 함수 호출에서는 ownership 규칙이 비교적 명확합니다. 하지만 멀티스레딩, 복잡한 데이터 구조 (트리, 그래프 등), 클로저, 또는 비동기 프로그래밍과 같이 데이터의 소유권과 생명 주기가 복잡하게 얽히는 시나리오에서는 규칙을 올바르게 적용하는 것이 훨씬 어려워집니다. 이때 Rc (Reference Counting), Arc (Atomic Reference Counting), RefCell, Mutex 등과 같은 스마트 포인터와 동시성 프리미티브를 사용해야 하며, 이들을 언제 어떻게 사용해야 할지 판단하는 것도 개발자의 몫입니다.
왜 '어렵다'고 느낄까?
Rust의 메모리 관리가 '어렵다'고 느껴지는 이유는 주로 다음과 같습니다:
* 기존 프로그래밍 패러다임과의 차이: 가비지 컬렉션이 있는 언어(Java, Python, Go 등)나 수동 메모리 관리를 하는 언어(C, C++)에 익숙한 개발자에게는 Rust의 Ownership 모델이 매우 생소하게 다가올 수 있습니다.
* 컴파일러 에러 메시지: 처음에는 컴파일러가 뱉어내는 소유권 및 라이프타임 관련 에러 메시지가 난해하게 느껴질 수 있습니다. 이는 컴파일러가 자세한 정보를 주려고 노력하는 것이지만, 익숙해지기 전까지는 좌절감을 줄 수도 있습니다.
* '정답'을 찾아야 하는 부담: C처럼 메모리 할당/해제 코드를 직접 작성하는 부담은 없지만, Rust는 컴파일러를 통과시키기 위해 메모리 접근 방식에 대한 '정답'을 찾아야 하는 부담을 줍니다. 이는 런타임에 발생할 수 있는 잠재적인 버그를 컴파일 시점으로 당겨와 해결하는 방식의 필연적인 결과입니다.
그럼에도 Rust의 가치
결국 Rust의 자동 메모리 관리는 개발자가 메모리 안전성 문제로 골치 아플 일을 컴파일러가 대신해주는 것에 가깝습니다. C처럼 일일이 free를 호출할 필요가 없으면서도, GC 언어처럼 런타임 오버헤드 없이 높은 성능을 유지할 수 있다는 점에서 혁신적인 접근 방식임은 틀림없습니다.
처음에는 어렵게 느껴질 수 있지만, Rust의 소유권 모델에 익숙해지면 오히려 메모리 관련 버그로부터 자유로워지고 훨씬 더 안정적이고 성능 좋은 코드를 작성할 수 있게 됩니다. 배우는 과정의 어려움은 궁극적으로 더 견고한 소프트웨어를 만드는 데 기여하는 셈입니다.