[Udemy 강의 후기] 요즘 핫한 Rust, 직접 한 번 먹어보겠습니다

맛있.. 다..?

Gordon Choi
10 min readApr 13, 2024

여는 말: 멋있잖아

필자는 기본적으로 지식욕이 높은 사람이다. 그렇기 때문에 맨날 보던 것을 개발하는 것이 지칠 때는 잠시 접어 두고, 새로운 것을 찾아보곤 한다. 무언가 꽤 새로운 것을 찍먹해 보면 환기되는 느낌이 들면서도, 낯선 것에서 오는 두려움으로 인해 자신이 하던 것으로 다시 돌아와 집중할 수 있게 되는, 나름의 선순환을 가지고 있다. 한편 학습하면서 기록해둔 지식은 사라지지 않기 때문에 나중에 정말로 필요한 순간이 생길 때 진입장벽을 조금 낮추어 주는 효과도 있기도 하고.

그렇다면 이 “찍먹”할 것을 선택할 때는 어떤 기준을 가지고 있느냐? 주로 끌리는 것을 그냥 고르는 편이다. Rust에 대해 배워보고 싶다고 생각한 계기도 또한 이러한 끌리는 지점이 많이 작용했다. C, C++ 등의 퍼포먼스 지향 언어를 대체하기 위해 나온 언어라는 것도 흥미로웠고, Swift를 만들 때 Rust의 영향을 많이 받았다는 이야기에 대해서도 호기심이 생겼다. 한편 그냥 멋있어 보여서 배워보고 싶은 마음도 있었다. 게다가 마침 최근 미 백악관에서 메모리 관리의 위험이 있는 C와 C++의 사용을 지양하자고 하면서 대체재로 예시를 든 언어가 Rust였기도 했다! 그 목록에 Swift도 포함되어 있는 것은 비밀.

이런저런 계기가 장작처럼 쌓여 있던 차에, 글또 X Udemy 챌린지가 여기에 불을 댕겼다. 글또 회원들에 한해 Udemy에서 제공되는 강의 중 최대 2개까지 선택해서 무료로 수강할 수 있는 기회가 온 것! 필자는 필자의 시간 배분을 고려해 하나의 강의만 들을 수 있을 것이라 생각했고, Flutter와 Rust 사이에서 꽤 고민했다. 결국은 쌓여 있는 동기가 Rust 쪽에 더 많아서, <Rust Programming 핵심 강의[한글 자막]>를 신청해 듣게 됐다.

감사합니다 글또 감사합니다 Udemy / 배너 제작: 최준호님

In a nutshell

Rust를 찍먹해보고 느낀 것

Rust의 대표적인 특징 하나를 꼽자면 역시 “소유권” 개념을 꼽을 수 있다. 특정 지점에서 선언되어 있는 상수나 변수를 같은 스코프 안의 함수의 파라미터로 쓴다면, 해당 상수/변수는 함수 실행이 끝난 시점에서 메모리에서 해제되는 것이다(!!!).

enum Light {
Bright,
Dull,
}

fn display_light(light: Light) {
match light {
Light::Bright => println!("Bright"),
Light::Dull => println!("Dull"),
}
// 함수 호출이 끝나면 이동한 소유권 light를 삭제한다.
}

fn main() {
// light 자료(의 메모리)의 소유권은 main 함수에 있다.
let light = Light::Dull;
// display_light 함수로 light의 소유권을 이동한다.
display_light(light);
// 이 함수 호출이 종료되는 순간 위에 정의한 light 변수는 삭제된다(!!!).
// 이미 소유권이 다른 함수로 이동했고, 함수가 종료되는 순간 삭제되었기 때문.

// 그래서 한 번 더 쓰려고 하면 에러가 발생한다.
display_light(light);
}

먼저 Bright와 Dull 두 개의 케이스를 가진 열거형 Light를 선언한다. display_light 함수에서는 입력받은 열거형 케이스(값)에 따라 특정 동작을 수행한다. 이 과정에서 light 파라미터에 미리 선언한 상수를 함수에 넣으면, 함수 실행이 끝나고 해당 상수는 삭제된다. 함수 실행 종료시 함수가 스택 메모리에서 해제될 때 함께 해제된다는 것이다. 소속된 스코프, “소유권”이 바뀐 것이다. 이를 소유권의 “이동” 이라고 한다. 위 코드에서 설명했듯, 그래서 한 번 더 해당 상수를 사용하려고 하면 컴파일러 상에서 에러를 반환한다.

이러한 use case에서 사용하기 위해 소유권 “대여”의 개념 또한 있다.

enum Light {
Bright,
Dull,
}

// & 기호로 대여임을 나타낸다. 이거 완전 포인터
// 사실 그냥 포인터 맞다. "참조" 라는 표현이 여러 번 등장한다.
fn display_light(light: &Light) {
match light {
Light::Bright => println!("Bright"),
Light::Dull => println!("Dull"),
}
// 함수 호출이 끝나도 대여받은 light의 소유권이 없기 때문에, 삭제되지 않는다.
}

fn main() {
// light 자료(의 메모리)의 소유권은 main 함수에 있다.
let light = Light::Dull;
// display_light 함수로 light의 소유권을 이동하지 않고 대여한다.
display_light(&light);
// 이 함수 호출이 종료되는 순간 위에 정의한 light 변수가 더 이상 삭제되지 않는다.

// 그래서 더 쓸 수 있다.
display_light(&light);
}
// 다만 main 함수가 끝나면 삭제된다. 소유권을 가진 함수가 종료되었기 때문.

코드에서도 설명했듯, 소유권 대여의 개념은 C에서의 포인터 개념과 유사하다. 값 타입인 light 상수를 마치 참조 타입처럼 사용한다. Swift의 inout 의 사용법과도 유사하다!

소유권이라는 용어에 대해 처음 접하다 보니 두려움이 앞섰지만, 이는 또한 Rust만의 메모리 관리 방법론이라는 생각이 들었다. 개발 언어들은 모두 메모리 관리에 대해 나름의 고민을 거친다. Java 계열 언어의 Garbage Collector, Swift의 Automatic Reference Counting 비슷한 친구인 것이다. 하지만 프로그램을 짜는 내내 어떤 변수가 소유권이 어디로 갔는지 계속 신경쓰려면 쉽지 않겠다는 생각도 들었다. 그렇다고 모든 변수를 한 번에 선언하고 소유권을 대여만 해 간다면 메모리 먹는 하마 같은 프로그램이 나올 뿐더러, 만약 비동기 작업이 있다면 비동기 작업 관련 문제도 발생할 수 있을 것이고. 그럼에도 불구하고 여러 모로 손에 익는다면 편안하게 코딩할 수 있겠다는 생각이 들었다.

한편 Swift와 유사한 구석도 있었는데, enum 자체가 그대로 값 타입으로 사용된다는 점, match문과 switch문은 일대일 대응을 시킬 수 있다는 점, 상술한 소유권 대여와 inout의 사용 등이 그렇다. 다른 언어에서 어떻게 되는지는 잘 모르지만, 최소한 필자가 사용/해독해 본 (몇 안 되는) 언어들 중에서는 Swift와 Rust가 가장 유사한 점을 가지고 있다고 느꼈다.

Rust 찍먹을 도와 준 <Rust Programming 핵심 강의>

https://www.udemy.com/course/rust-programming-korean/

필자의 Rust 찍먹에 아주 큰 도움을 준 <Rust Programming 핵심 강의>! 개발 관련 기초적인 지식만 있으면 들을 수 있다고 한다. 정말일까~ 필자가 들어보고 난 후기를 써 보도록 하겠다.

Pros

필자가 꼽는 이 강의의 가장 큰 장점은 설명이 아주 디테일하다는 것이다. Rust의 기초, 개발의 기초부터 차근차근 설명해 준다. 게다가 한글 자막이 있으니 듣기 어렵지도 않고, 강의가 잘게 나누어져 있어 부담없이 하나씩 들을 수도 있다. 실습 과정도 나름 충실하게 갖추어져 있어, 코딩의 원초적인 재미인 “짠 대로 작동하는 재미” 를 느낄 수 있다. 배울 때는 역시 재미있는 게 가장 중요하지 않겠는가? 개인적으로는 개발에 대해 전혀 몰랐어도 관심만 있다면 듣기에 무리가 없다고 느꼈다.

예시나 실습 코드를 설명하는 과정에서, 한 줄씩 천천히 짚어 내려가며 각각의 코드가 무슨 뜻인지 설명해 준다. 이 부분에서 이 변수는 어디로 이동하는지 등을 그림을 그려 가며 세세히 설명해 줌으로써 이해를 돕는다.

몹시 친절하다

한편 Rust뿐만 아니라, 컴퓨터 사이언스 측면에서 이루어지는 설명이 생각할 거리를 남겨 준다. 변수와 상수의 할당을 “데이터를 임시로 메모리에 할당하는 방법” 이라고 말해 줌으로써, 추상화의 장막에 숨겨진 컴퓨터의 작동에 대해 귀띔해 준다. 한편 enum은 하나의 상태를, struct는 여러 개의 상태를 가진 자료다! 라고 설명함으로써, DB 관점에서 타입을 설명해주기도 한다. 개발자로서 한 번쯤 생각해봐야 할 관점에서 설명해주는 스타일이 좋다고 느꼈다.

Cons

전반적으로 너무 좋은 강의였지만, 들으면서 단 하나 헷갈렸던 점이 있었다. Rust 개발 환경으로 VSCode를 활용해 강의가 진행되는데, VSCode는 코드를 작성한 후 cmd+s를 눌러 저장하지 않으면 변경 사항이 반영되지 않는다(!!!). 물론 개인의 개발 환경에 따라 다를 수 있겠지만, 적어도 개발을 처음 시작하는 사람 입장에서는 헷갈릴 수 있는 부분이라고 생각한다.

필자 또한 이 이슈 때문에 콘솔에서 cargo를 사용해 컴파일할 때 작성한 코드가 반영되지 않아 헷갈리고 분노 — 무지했기 때문 — 한 기억이 난다. 환경설정 강의 파트에서 언급되지 않았던 부분이라, AI의 도움을 받아 겨우 해결했다. 강의를 처음 들을 때 이것 때문에 꽤 삽질을 했어서, 이 부분에 대해 조금 더 설명해주면 좋지 않았을까 하는 아쉬움은 있었다. 개발 환경으로 VSCode를 선택해서 강의하기 때문에 더더욱 그 부분에 대한 설명이 필요하다고 생각했다. 물론 이 글을 보는 독자분들께서는 이 문제점을 이미 파악했기 때문에 필자와 같은 시행착오를 겪지는 않을 것이다. 그렇다면 거의 무결점 강의를 들을 수 있는 기회가 제공되는 셈.

닫는 말: 폴리글랏을 꿈꾸며

폴리글랏이란 간단히 말해 여러 언어를 사용할 줄 아는 개발자를 일컫는다. 개발 언어 하나에 대해서도 숙련도를 갖추기는 어렵기 때문에, 경외감 어린 시선으로 불리는 경우가 많은 칭호이다. 하지만 이 강의를 수강하면서, 개발자에게 있어 결국 언어나 프레임워크는 사실 그냥 도구라는 생각을 했다. 개발자는 기술로서 가치를 창출하는 직업이다. 또한 필자가 지망하는 모바일 개발자는 언제 어디서나 사용자가 원하는 가치를 얻게 하는 데 그 의의가 있다. 이를 위해서는 기술 편식을 하지 않아야 한다. 언제, 어디서든 가치를 제공하겠다고 약속한 것이니까, 사용자 중심으로 생각해야지 개발자 중심으로만 생각하면 곤란하다고 여기고 있다. Rust 강의를 수강한 경험은 필자가 지향하는 이러한 바를 확실히 하는 또 하나의 값진 경험으로서 필자의 책갈피에 저장되었다.

개발자로 살아가며 평생 개발해야 하는 입장에서, 개발은 때로 지난하고 지치는 과정일 수 있다. 익숙함에서 오는 피로감은 누적되고, 생산성을 저해하는 결과를 낳는다. 이럴 때 가볍게 엿볼 만 한 개발 관련된 무언가에 눈을 돌려 보는 것도 좋다는 생각을 했다. 적어도 필자에게 있어서는, 잠시 Rust에 발을 담가 본 것이 개발자로서의 행동 양식을 공고히 함과 동시에 생각의 폭을 넓히는 경험이었다. 이를 통해 원래 하던 것에도 적용할 수 있는 지식을 얻고, 새로운 것에는 흥미를 남겨 둠으로써 지속 가능한 개발자로 거듭나기 위한 새로운 한 걸음을 내딛는 계기가 되었다고 느낀다.

--

--