본문 바로가기

Rust/Basic

[Rust Tutorial] 1 - Introduce

 

 


 

Intro

최근 들어 저는 Rust를 시작했습니다. 개발경력이 C embedded를 시작으로 해서 최근은 Python Application에 몸담고 있는 와중에 Rust를 왜 시작하게 되었을까요? Rust는 저에게 꽤 이상적인(실용적인지는 아직 잘 모르겠습니다) 언어였기 때문입니다. 개인적으로 느낀 Rust의 감상은 2가지 입니다.

 

Rust에 대한 개인적인 감상

1. GC가 없다.

GC로 인해 내가 Memory를 관리하지 않아도 되지만, 그것은 즉 memory에 대한 내가 세부적으로 제어할 수 없는 내부 동작이 있다는 의미이기도 합니다. 이는 곧 성능 최적화를 방해하는 요소가 되기도 합니다. 요즘 언어들은 대부분 GC를 가지고 있습니다. Java부터 Python, Javascript까지 요즘 Application을 담당하는 언어 중 GC가 없는 언어는 없다고 봅니다. GC가 없는 언어는 C/C++이 여전히 Major합니다. 이전에는 C를 많이 다뤄서 C로 알고리즘 문제도 많이 풀고는 했는데 Python을 꽤 쓰다보니 개발 속도는 늘었지만 C만의 그 빡빡하면서도 Machine의 성능을 잘 뽑아냈던 그 경험이 많이 그리웠습니다.

 

2. 현대적이다.

C/C++은 자유도가 꽤 높아 개발자의 실수나 관리 미숙이 Compiler에서 잡히지 않고 Runtime에서 null pointer같은 문제로 Program을 panic에 빠뜨리기 쉽다는 문제가 있습니다. 물론 smart pointer같은 C++11 표준이 들어오기는 했지만 뭔가 부족했습니다. 이런 문제들을 Compiler가 잡아줄 수 없을까, 최신의 철학과 많은 경험을 포함하여 새로 만들어진 언어가 없을까 하던 차에 Rust를 알게 되었습니다. Rust는 C++가 가지고 있는 "개발자가 저지를 수 있는 실수"를 "compile time"에서 잡을 수 있도록 다양한 규칙을 두고 있습니다. (물론 이 규칙이 C++의 모든 문제를 해결할 수 있다는 것은 아닙니다.)

문제 C++ Rust
Dangling Pointer 객체를 Delete한 후에도 객체를 가리키는 pointer가 남는 경우 Ownership과 Lifetime으로 메모리 해제 후에 포인터가 남지 않도록 합니다.
Double Free 동일한 메모리를 두 번 해제하려 하는 행위 Ownership으로 하나의 자원은 하나의 소유자만 가질 수 있음. Scope를 벗어나면 자원이 자동으로 해제되어 double free가 발생할 가능성을 원천 차단합니다.
Use After Free 객체의 메모리를 해제한 후에도 해당 포인터를 통해 접근하려는 행위 Ownership으로 하나의 자원은 하나의 소유자만 가질 수 있음. Scope를 벗어나면 자원이 자동으로 해제되어 double free가 발생할 가능성을 원천 차단합니다.
Data Race 멀티스레드 환경에서 두개 이상의 스레드가 동시에 동일한 메모리 위치를 읽고 쓰려고 하는 행위. 동시성 안정성(Concurrency Safety)를 Compiler level에서 보장. Rust의 borrow checker는 동일한 메모리에 여러개의 가변참조를 허용하지 않음. 다중 스레드 사용 시 안전한 동기화 메커니즘을 강제함.
Unchecked Type Casting reinterpret_cast 등을 통해 Unchecked Type Casting이 가능하므로 실수로 잘못된 Type변환 잠재성이 있음. 안전하지 않은 Type Casting을 엄격하게 제안함. 만약 위험한 Casting이 필요한 경우 unsafe block안에서만 수행할 수 있므으로 위험한 Casting에 대한 명시적 표기를 할 수 있음
Null Pointer Dereference nullptr가 있음. 역참조 하면 프로그램 충돌. rust는 null값이 없음. 대신 Option를 통해 Some, None 확인 후 값을 명시적으로 처리
Manual Memory Management 메모리 관리를 직접 수행해야 하므로 메모리 누수, 메모리를 잘못 해제하는 잠재적 위험이 있음 Borrowing mechanism은 메모리 누수를 줄여주며 일반적인 상황에서는 메모리 해제를 수동적으로 할 필요가 없음.

 

요약하자면, Rust의 Programming 규칙들은 C++에서 "개발자의 실수로 인해" 발생할 수 있는 다양한 메모리 관리 문제와 동시성 문제를 방지하기 위해 설계되었다는 것입니다.

 

이런 특성들은 Rust에 C embedded의 HW적인 static한 성격과 현대적인 Python의 편리함을 동시에 만족하는 언어라는 생각이 들게 되었고, 저는 Side Project를 Rust로 시작하게 되었습니다.

 

Rust를 좀 더 공부해 보자 많은 분야에서 사용이 가능하다는 것을 알게 되었습니다.

  1. System Programming
  2. Embedded System
  3. Web application Backend server (Actix, Rocket)
  4. Web Application Frontend wasm (Yew, Leptos)
  5. Game Application (Bevy)
  6. Blockchain (Solana, Polkadot)
  7. Data Engineering (Polars)

 

생각보다 많은 분야에서 Rust는 사용할 수 있다는 것을 알 수 있습니다 그렇다면 rust는 C++을 대체할 수 있을까요?

 


 

그래서 Rust는 C++을 대체할 수 있는가?

Rust의 장점이 많음에도 불구하고 여전히 Rust는 C++을 넘어야 할 여러가지 벽이 있습니다.

 

  • 기존 코드와 생태계의 방대함 : 수십년간 쌓아온 방대한 코드베이스와 라이브러리, 개발자 Pool의 크기를 비교하면 Rust는 C++의 규모를 따라 잡기에는 아직 한참 멀었습니다.
  • Low Level System Programming과의 호환성 : Kernel, Driver, Firmware, H/W 접근 분야에서 C/C++은 표준이나 다름없습니다. Rust는 아직 이런 분야에서 표준으로 불리기는 어렵습니다.
  • Tool Chain : 다양한 플랫폼과 Compiler, debugger, Profiler와 같은 도구들이 오랜 시간동안 성숙해 왔습니다. GCC, Clang같은 Compiler가 대표적입니다. Rust의 프로젝트 관리자인 cargo나 compiler인 rustc도 좋은 tool이지만 C++ 수준의 다양한 분야의 지원 측면에 대해선 제한적입니다.
  • C++과의 호환성 : C++을 대체한다는 것은 C++과의 호환성도 어느정도 수준에 올라와야 합니다. C의 경우 extern "C"로 어느정도 수준은 지원 하지만 C++의 vtable, exception handling, template metaprogramming같은 영역에서는 Rust의 직접 호환을 기대하기 어렵습니다.
  • Learning curve : C++의 교육자료, 커뮤니티는 몇십년동안 발전해 왔습니다. 반면 rust는 비교적 새로운 언어입니다. 교육자료나 커뮤니티가 성숙할 시간이 더 필요할 것입니다. (rust 1.0은 2015년 05월 15일에 release되었습니다.)
    특히 Rust의 엄격한 메모리 안전 규칙을 위한 Ownership, Borrowing rule과 같은 규칙은 다른 Programming에서는 볼 수 없는 완전 독창적이며 새로운 규칙입니다. 이는 Rust의 학습곡선을 더욱 가파르게 만들 수 있습니다.
    (물론 Senior 수준에 다다르는데는 C++이 더 오래 걸릴 수도 있습니다ㅎㅎ)

Rust에 대한 설명은 이 정도로 충분한 것 같습니다. 이제 Rust의 문법에 대해서 간단한 Code를 작성해 보도록 하겠습니다.

 


Tutorial

Rust 1.79.0 (released 2024-06-13) 

 


 

 

* reference

 - https://doc.rust-lang.org/book/

'Rust > Basic' 카테고리의 다른 글

[Rust Tutorial] 6 - Control Flow  (0) 2024.11.17
[Rust Tutorial] 5 - Function  (0) 2024.11.17
[Rust Tutorial] 4 - Data Type  (0) 2024.11.14
[Rust Tutorial] 3 - Variables  (0) 2024.11.14
[Rust Tutorial] 2 - Cargo 사용법  (0) 2024.11.14