요즘IT
위시켓
최근 검색어
전체 삭제
최근 검색어가 없습니다.

Rust. 최근 레딧(Reddit)이나 해커뉴스(HackerNews)를 보면 아주 빈번하게 접할 수 있는 프로그래밍 언어입니다.

회원가입을 하면 원하는 문장을
저장할 수 있어요!

다음

회원가입을 하면
성장에 도움이 되는 콘텐츠를
스크랩할 수 있어요!

확인

개발

Rust는 C++을 대체할 수 있을까?

년차,
어떤 스킬
,
어떤 직무
독자들이 봤을까요?
어떤 독자들이 봤는지 궁금하다면?
로그인

Rust. 최근 레딧(Reddit)이나 해커뉴스(HackerNews)를 보면 아주 빈번하게 접할 수 있는 프로그래밍 언어입니다.

 

이 언어는 C++을 대체할 수 있는 언어로 유명한데요. C++의 오랜 사용자 입장에서 Rust가 과연 어떤 메커니즘으로 C++을 대체하고자 하는지 알아두면 좋은 시점이라고 생각했습니다.

 

과연 Rust는 어떤 특징이 있길래, 이렇게 인기를 얻고 있는 걸까요?

 

Rust! 어떤 언어인지 아시나요?

Rust는 누가 만들었을까?

Rust는 지난 2010년, 모질라 재단의 후원으로 개발된 프로그래밍 언어입니다. 모질라 재단은 파이어폭스와 썬더버드 같은 유명한 오픈 소스 프로젝트로 잘 알려져 있습니다. 초기 개발자는 그레이던 호어(Graydon Hoare)로 모질라에서 근무하며 Rust의 기본 아이디어를 구상하고 구현하기 시작했다고 합니다. 호어의 개인 프로젝트였던 Rust는 곧 모질라 재단의 공식적인 지원을 받게 되었고, 2020년 Rust 재단이 설립되며 언어 개발과 생태계가 더욱 활발해졌습니다.

 

이러한 Rust는 시스템 프로그래밍 언어로, 특히 C와 C++의 단점을 보완하고자 하는 목적에서 탄생했습니다. 더 나은 안정성과 성능, 특히 병렬 처리의 안전성을 핵심 목표로 개발되었죠.

 

Rust의 5가지 특징을 알아봅시다

Rust의 주요 특징은 이렇습니다.

 

  • 높은 메모리 안전성: 컴파일 시점에서 메모리 접근 오류를 방지함으로써 런타임에 발생할 수 있는 여러 오류를 사전에 차단합니다.
  • 뛰어난 성능: C, C++과 유사한 수준의 고성능을 제공합니다.
  • 병렬 처리의 안전성: 데이터 경합을 방지하고 안전한 병렬 처리를 지원합니다.
  • 고유 소유권 시스템: 고유한 소유권 시스템인 ‘빌림 검사기(Borrow Checker)’ 도입으로 메모리 관리의 효율성을 극대화합니다.
  • 풍부한 타입 시스템과 패턴 매칭: 다양한 타입 시스템과 패턴 매칭을 적용해 코드의 안전성과 가독성을 높이는 데 기여합니다.

 

어째서 실리콘 밸리에선 이렇게 핫할까요?

Rust는 실리콘 밸리의 주요 기업들로부터 관심을 받고 있습니다. 나사, 마이크로소프트, 리눅스 커뮤니티, 안드로이드 프로젝트 등 여러 곳에서 개발 언어로 Rust를 선택하고 있죠. 특히 새로 도입할 기술을 결정하는 관점이 아닌 기존 C++ 코드를 재작성 하는 선택지로 많이 쓰이고 있습니다. (참고 글)

 

여러 가지 Rust의 특징 중에서도 아래 특징이 큰 영향을 주었을 겁니다.

 

  • 안정성: 메모리 안전성과 병렬 처리 안전성을 보장하여 소프트웨어의 안정성을 높일 수 있습니다.
  • 성능: 시스템 프로그래밍 언어로서 C++와 동등한 성능을 제공하면서도, 더 나은 메모리 관리 기능을 갖추고 있습니다.
  • 생산성: Rust의 강제된 메모리 관리 규칙과 문법, 또한 실수의 여지를 줄이는 규칙은 초기 학습 비용이 크지만, 이에 적응한 개발자들의 생산성과 안정성을 올려줍니다.

 

 

C++ vs. Rust. 그래서 무엇이 다른가요?

하나하나 짚어보며 차이점을 알아볼까요?

 

1. 메모리 안전성

  • C와 C++: C와 C++은 수동 메모리 관리를 요구합니다. 따라서 개발자가 직접 메모리를 할당하고 해제해야 하는데요. 그 때문에 메모리 누수, 잘못된 메모리 접근(예: 댕글링 포인터, 버퍼 오버플로우) 같은 문제가 발생하기 쉽습니다.

 

  • Rust: Rust는 고유한 소유권 시스템 ‘빌림 검사기(Borrow Checker)’를 적용해 메모리를 자동으로 관리합니다. 이 시스템은 컴파일 타임에 메모리 안전성을 보장하고, 댕글링 포인터나 버퍼 오버플로우 같은 메모리 접근 관련 문제를 방지합니다. 또한 생명주기(Lifetime) 시스템에서 참조가 유효한 기간을 명시적으로 관리하며 메모리 안전성을 강화합니다.

 

2. 병렬 처리의 안전성

  • C와 C++: 이 언어를 쓰면 병렬 처리를 구현할 때 데이터 경합 조건(race condition)을 방지하기 어렵습니다. 무엇보다 개발자가 직접 동기화 메커니즘을 사용해야 하는데, 잘못된 동기화는 치명적인 버그를 초래할 수 있습니다.

 

  • Rust: Rust 표준 라이브러리에서 제공하는 Send와 Sync 트레잇으로 안전한 병렬 처리를 지원합니다. 이 트레잇들은 타입 시스템에 의해 강제되며, 데이터 경합 조건을 컴파일 타임에 방지합니다. 또한 안전한 병렬 처리(fearless concurrency)를 장려하며, 데이터 경합 없이 병렬 코드를 작성할 수 있도록 설계되었습니다.

 

3. 에러 처리

  • C와 C++: C는 기본적으로 예외 처리를 지원하지 않습니다. 그래도 C++는 예외 처리 메커니즘을 제공하지만, 잘못 사용하면 프로그램의 안정성을 해칠 수 있습니다.

 

  • Rust: Rust는 Result와 Option이라는 타입으로 명시적인 에러 처리를 강제합니다. 이 타입들을 사용하면 함수가 성공하거나 실패할 때의 결과를 명확하게 표현할 수 있으며, 에러 처리를 강제하여 안전한 코드를 작성할 수 있습니다. 또한 Rust는 비정상 종료가 필요할 때 panic! 매크로를 사용해 명시적으로 프로그램을 중단시킵니다. 이로써 예외 처리를 명확하게 하고, 예상치 못한 오류를 방지할 수 있죠.

 

4. 현대적 문법과 생산성

  • C와 C++: C와 C++는 오래된 언어입니다. 따라서 현대적인 개발 패턴을 적용하기 어렵고, 문법은 복잡하며, 코드 유지보수가 어렵습니다.

 

  • Rust: Rust는 최근에 만들어진 프로그래밍 언어인 만큼, 모던한 문법을 채택해 코드의 가독성과 유지보수성을 높였습니다. 매크로 시스템, 패턴 매칭, 그리고 강력한 타입 시스템이 대표적인 예시입니다. 여기에 Cargo라는 빌드 및 패키지 관리 도구로 라이브러리 의존성을 쉽게 관리하고, 빌드 과정을 단순화합니다.

 

5. 성능

  • C와 C++: C와 C++는 낮은 수준의 제어를 지원합니다. 이러한 제어는 버그와 안전성 문제를 유발할 수 있습니다.

 

  • Rust: Rust는 고성능을 유지하면서도 안전한 추상화를 제공합니다. 이러한 제로 비용 추상화 원칙으로 런타임 오버헤드 없이 안전한 코드를 작성할 수 있습니다.

 

예시 코드로 Rust의 특징을 자세히 알아봅시다

1. 동적 메모리 관리

메모리를 동적으로 관리하는 것은 현대 언어에서는 소수 언어만 가진 특징입니다. 메모리를 잘 관리하면 고성능 애플리케이션을 만들 수 있습니다. 대신 실수의 여지가 있죠.

 

수동으로 메모리 할당 해제를 해야 하는 것은 C++ 문법의 단점입니다. 물론 C++의 경우에도 스마트 포인터를 쓰면 보강되긴 하지만, 강제된 규칙은 아닙니다. 따라서 C++의 표준적인 메모리 관리 규칙에서는 엄연한 단점이라고 볼 수 있습니다.

 

C++ 코드 <출처: 작가>

 

여기서 delete 키워드를 활용한 메모리 해제 부분을 누락한다면, 메모리 누수가 발생하게 됩니다.

 

Rust 코드 <출처: 작가>

 

예시 코드에서 my_object는 use_my_class 함수 끝에서 자동으로 소멸하며 메모리가 해제됩니다. 이처럼 Rust의 소유권 시스템은 자동으로 메모리를 관리합니다.사실 이러한 규칙은 C++의 스마트 포인터, 그리고 자바 등 레퍼런스 카운팅 기반의 Garbage Collection으로 잘 구현되어 있습니다. 색다를 것 없다고 느낄 수도 있겠죠.

 

그러나 차이가 없다면, Rust가 지금보다 주목을 덜 받았을 겁니다. Rust의 소유권 시스템에 대해 더 자세히 알아봅시다.

 

2. 생명 주기와 소유권 시스템

C++에서는 개발자가 직접 메모리를 관리해야 합니다. 따라서 메모리 해제를 잊어버리는 경우, 메모리 누수가 발생할 수 있습니다. 또한, 동일한 메모리를 여러 포인터가 참조할 때 발생할 수 있는 댕글링 포인터(Dangling Pointer, 주인 잃은 포인터) 문제도 존재합니다.

 

Rust는 소유권 시스템을 통해 이러한 문제를 방지합니다. 여기서 소유권(Ownership)이란, 각 값은 오직 하나의 소유자만 가질 수 있으며, 소유자가 범위를 벗어나면 값은 자동으로 해제된다는 것을 뜻합니다.

 

이러한 시스템은 빌림과 생명주기로 구현되죠.

 

  • 빌림(Borrowing): 값을 참조할 때는 불변 참조(&T)와 가변 참조(&mut T)를 사용합니다.
  • 생명주기(Lifetime): 참조의 유효 기간을 컴파일 타임에 검사하여 안전성을 보장합니다.

 

C++ 코드 <출처: 작가>
Rust 코드 <출처: 작가>

 

C++에서는 참조를 통해 빌림을 구현하지만, Rust에서는 불변 참조(&T)로 빌림을 구현하고 소유권을 옮기지 않습니다. 무엇보다 이러한 Rust의 소유권 시스템과 생명주기 규칙은 컴파일 타임에 참조의 유효성을 검사하여 안전성을 보장합니다.

 

3. 데이터 경합(Race) 방지

Rust의 소유권 시스템과 생명주기 개념은 병렬 처리와 안정성에서 많은 장점을 제공합니다. 특히, Rust의 타입 시스템과 빌림 검사기(Borrow Checker)는 데이터 경합을 방지함으로써 안전한 병렬 프로그래밍을 지원하죠.

 

데이터 경합이란 여러 스레드가 동시에 같은 데이터를 수정하려 할 때 발생하는 문제입니다. 이런 데이터 경합이 발생하면 예상치 못한 결과나 프로그램 오류가 발생할 수 있습니다. Rust는 컴파일 타임에 데이터 경합을 방지하는 메커니즘을 제공합니다. 이로써 높은 성능과 안정성을 동시에 추구할 수 있습니다.

 

Rust 코드 <출처: 작가>

 

코드 상단의 Arc, Mutex가 보이시나요? Arc(Atomic Reference Counting) 개념은 여러 스레드 간에 소유권을 안전하게 공유할 수 있게 합니다. 또한 Mutex는 상호 배제로 여러 스레드가 동시에 데이터에 접근하지 못하도록 합니다.

 

이처럼 Rust의 타입 시스템은 Arc와 Mutex를 사용하여 데이터 경합을 방지합니다. Arc는 안전하게 참조를 공유하고, Mutex는 데이터 접근을 동기화하여 경합을 방지합니다.

 

4. 소유권과 빌림 시스템의 안전성

Rust의 소유권과 빌림 시스템은 데이터 경합을 방지할 뿐만 아니라, 컴파일 타임에 데이터 접근의 안전성을 보장합니다. 이는 런타임에 발생할 수 있는 많은 오류를 사전에 방지합니다.

 

특히 Rust의 빌림 규칙은 불변 참조(&T)와 가변 참조(&mut T)를 명확하게 구분합니다. 이러한 규칙으로 데이터의 일관성을 유지하고, 데이터 경합을 방지합니다.

 

Rust에서 불변 참조와 가변 참조는 동시에 존재할 수 없습니다. 이는 데이터의 일관성을 유지하고 안전한 동시성을 보장합니다. 컴파일러 역시 이러한 규칙을 강제하여, 불변 참조와 가변 참조가 동시에 존재하지 않도록 합니다.

 

Rust 코드 <출처: 작가>

 

5. Send와 Sync 트레잇

Rust의 Send와 Sync 트레잇은 병렬 프로그래밍에서 안전성을 보장하는 중요한 역할을 합니다. 만약 타입이 Send 트레잇을 구현하면, 해당 타입의 값이 다른 스레드로 안전하게 이동할 수 있음을 의미합니다. 반면 Sync 트레잇을 구현하면, 해당 타입의 값이 여러 스레드에서 동시에 접근할 수 있죠.

 

Rust 코드 <출처: 작가>

 

위 코드에서 vec![1, 2, 3]은 Send 트레잇을 구현하므로 스레드 사이를 안전하게 이동할 수 있습니다. 또한 Rust 컴파일러는 Send와 Sync 트레잇으로 스레드 간 데이터 이동과 공유의 안전성을 검사합니다.

 

6. 안전한 병렬 처리

Rust는 여러 도구와 패턴을 제공해 안전한 병렬 처리(Fearless Concurrency)를 실현합니다. 이렇게 개발자가 데이터 경합이나 동시성 버그를 두려워하지 않고, 병렬 코드를 작성할 수 있도록 도와줍니다. Arc, Mutex, RwLock 등이 병렬 프로그래밍에서 데이터의 안전한 공유를 가능하게 해주며, 채널(Channel)이 스레드 사이 통신을 안전하게 처리할 수 있도록 지원합니다.

 

 

Rust를 지금 배워도 될까요?

Rust는 배우기 쉬운가요?

Rust는 배우기 쉬운 언어는 아닙니다. 그러나 Rust를 익힌 사람이 많아졌고, 점점 더 늘어나고 있는 걸 보았을 때, 시간을 충분히 들이면 학습할 수 있겠죠. 특히 독특한 소유권 시스템과 생명 주기 규칙이 처음에는 이해하기 어려울 수 있습니다. 그러나 그만큼 개념을 익혔을 때, 안전하고 효율적인 코드를 작성하는 데 큰 도움이 됩니다.

 

앞으로도 Rust의 인기가 더 높아질까요?

앞서 보았듯 Rust는 이미 개발자들 사이에서 인기를 얻고 있습니다. 그 인기는 계속 높아질 것으로 보입니다. 안정성과 성능, 병렬 처리 특화 덕분에 다양한 산업 분야에서 Rust를 채택하고 있기 때문이죠.

 

Rust 재단의 적극적인 지원과 활발한 커뮤니티 활동, 여러 빅테크 기업과 제품에서 사용하는 추세 역시 이를 뒷받침합니다. C++을 여전히 많이 사용하는 마이크로소프트를 비롯해서 메타, 나사 등이 Rust를 다양한 로우 레벨 구현 언어로 채택하고 있죠. (참고 글)

 

한국에서는 대세로 보기 어렵습니다

그러나 한국에서는 아직 Rust를 대중적으로 널리 쓰고 있지 않습니다. 여전히 Java, JavaScript, Python 등이 주류로 Rust를 채택한 사례는 상대적으로 매우 적습니다. 로우 레벨의 SDK 등을 만드는 기업들도 대부분 Rust보다는 C++을 사용하는 편이고요. 그러니 한국에서 Rust를 배운다 해도 이직에 직접적인 도움이 되기는 어렵다고 생각합니다.

 

하지만 배워 둔다면 다양한 이득을 얻을 수 있습니다

Rust는 시스템 프로그래밍, 웹 개발, 임베디드 시스템 등 다양한 분야에서 유용하게 사용될 수 있는 언어입니다. 메모리 안전성과 병렬 처리 안전성이 애플리케이션에 있어 아주 중요한 요소이기 때문이기도 하죠.

 

하지만 웹 개발에서 강점도 있다는 점을 모르시는 분들이 많은데요. Rust는 마찬가지로 다양한 웹 프레임워크를 가지고 있습니다. Rust를 배우다 보면 병렬 처리에 대한 인사이트, 성능 이슈를 해결할 추가적인 선택지, 안정적인 애플리케이션을 만드는 또다른 방법 등을 익힐 수 있습니다. 또한 클라우드 서비스가 은근슬쩍 자꾸만 비싸지는 이 시점에 유의미한 금전적 의미도 있습니다. 서비스의 트래픽이 늘어날수록 성능 이슈를 해결하는 것만으로 큰 비용을 아낄 수 있으니까요.

 

 

마치며

정리해 보겠습니다. Rust는 뛰어난 안정성과 높은 성능, 안전한 병렬 처리를 제공하는 현대적인 시스템 프로그래밍 언어입니다. 실리콘 밸리 주요 기업들로부터 큰 관심을 받고 있으며 앞으로도 인기가 계속 증가할 것으로 예상됩니다. 물론 한국에서는 아직 대중적으로 널리 사용되지 않지만, Rust를 배워둔다면 다양한 분야에서 경쟁력을 갖출 수 있다고 보입니다.

 

무엇보다 이 언어는 충분히 성숙한 언어입니다. 특히 Rust를 배우는 과정에서 병렬 처리와 안정적인 메모리 관리를 이해할 수 있다면, 여러분도 특별한 개발자로 성장할 수 있을 겁니다.

 

요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.

좋아요

댓글

공유

공유

작가 '엘키'
17
명 알림 받는 중

작가 홈

작가 '엘키'
17
명 알림 받는 중
크래프톤, 넷마블, NHN 등을 거친 게임 개발자 이자, 웹 개발자입니다.

기록 집착자이며, 글 쓰기를 취미로 하고 있습니다.

C++를 커리오 초기 10년간 다뤘으며, 이후에는 자바, Ruby, Python, C#, Type Script 등 다양한 언어나 기술에 관심이 많습니다.

업무와 학습하며 얻는 인사이트를 다양한 글로 공유하고 싶습니다.

좋아요

댓글

스크랩

공유

공유

요즘IT가 PICK한 뉴스레터를 매주 목요일에 만나보세요

요즘IT가 PICK한 뉴스레터를
매주 목요일에 만나보세요

뉴스레터를 구독하려면 동의가 필요합니다.
https://auth.wishket.com/login