ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Day 3: Ownership & Borrowing
    RUST 20일 과정 2025. 1. 6. 13:36
    Day 3: Ownership & Borrowing

    Day 3: Ownership & Borrowing

    1. 수업 개요

    • 주제: Rust의 핵심 철학인 Ownership(소유권)과 Borrowing(빌려 쓰기) 개념 이해
    • 학습 목표:
      • Rust에서의 스택과 힙, 메모리 구조를 파악한다.
      • Ownership 규칙을 이해하고, Move/Copy가 어떻게 작동하는지 예제를 통해 확인한다.
      • Borrowing(&, &mut)을 통해 변수(메모리)를 안전하게 공유하는 방식을 익힌다.
      • 문자열 슬라이스 등 Slice 개념을 이해하고 실습해본다.

    2. 이론

    스택(Stack)과 힙(Heap)

    • 스택: 함수 호출 시 빠르게 할당/해제되는 정적 메모리 구역
    • 힙: 동적 메모리 할당이 이루어지는 공간 (Box, String, Vec 등은 힙 메모리를 사용)

    Ownership(소유권) 규칙

    • 규칙 1: 각 값(value)은 오직 하나의 Owner(소유자) 변수만 가진다.
    • 규칙 2: Owner(소유자)가 스코프를 벗어나면, 그 값은 자동으로 메모리 해제된다(Drop).
    • 예시:
    • {
          let s = String::from("Hello");
          // 여기서 s는 "Hello" 문자열의 소유자
      } 
      // 스코프 밖으로 나가면 s는 Drop되어 메모리가 해제됨

    Move(이동)와 Copy(복사)

    • Move: 힙 데이터를 가진 변수를 다른 변수에 할당할 때, 소유권이 넘어간다.
    • let s1 = String::from("Rust");
      let s2 = s1; 
      // s1 -> s2 로 소유권이 이동(Move)
      // 이제 s1은 유효하지 않음
    • Copy: 스택 데이터(정수, 부동소수점, 불리언, 문자 등)는 할당 시 복사가 일어남.
    • let x = 5;
      let y = x; 
      // x와 y 모두 유효

    Borrowing(대여, 참조)

    • 불변 참조(&): 읽기 전용 접근
    • 가변 참조(&mut): 읽고/쓰기가 모두 가능하지만, 특정 시점에 오직 하나만 허용
    • fn main() {
          let mut s = String::from("Hello");
          // 불변 참조
          let r1 = &s;         
          let r2 = &s;         
          // 가변 참조
          let r3 = &mut s;     
          // 불변 참조와 가변 참조를 동시에 사용하는 것은 컴파일 에러
      }
    • 규칙:
      • 동시에 여러 불변 참조는 가능
      • 가변 참조는 한 번에 하나만 가능 (데이터 레이스 방지)
      • 참조는 유효 범위 내에서만 사용 가능 (Owner 스코프가 끝나면 무효)

    Slice(슬라이스) 기초

    • 문자열이나 배열의 특정 구간을 참조하는 방법
    • &str, [T] 등의 슬라이스
    • let greeting = String::from("Hello Rust");
      let hello = &greeting[0..5];  // "Hello"
      let rust = &greeting[6..];    // "Rust"
      // greeting이 스코프를 벗어나면 hello, rust도 사용 불가

    3. 실습

    Move, Copy 개념 실습

    • String 타입 변수를 선언하고, 다른 변수에 대입해본다.
    • 소유권이 이동한 뒤 원래 변수를 사용하면 컴파일 에러가 발생함을 확인한다.
    • 정수형 변수를 복사할 땐 문제가 없음을 비교해본다.

    Borrowing 실습

    fn main() {
        let s1 = String::from("Borrow me");
        let len = calculate_length(&s1);  
        println!("'{}'의 길이는 {}", s1, len);
    }
    
    fn calculate_length(s: &String) -> usize {
        s.len()
    }

    문자열 슬라이스 실습

    • 문자열의 특정 구간을 슬라이스로 추출해 출력
    • 슬라이스로 반환하는 함수를 작성해보기:
    • fn first_word(s: &String) -> &str {
          // 공백이나 특정 문자를 만나기 전까지의 단어를 슬라이스로 반환
      }

    4. 마무리 및 과제

    오늘 배운 내용 정리

    • Ownership: 소유권과 스코프가 연동되어 메모리 관리가 자동화됨
    • Move/Copy: 힙 데이터 vs 스택 데이터
    • Borrowing: 불변 참조 & 가변 참조 사용 시 주의 사항
    • Slice(슬라이스) 개념과 문자열 슬라이스 활용

    과제(실습 문제)

    1. 다음 코드에서 발생하는 에러를 해결해보자:
    2. fn main() {
          let mut text = String::from("Day3");
          let ref1 = &text;
          let ref2 = &mut text;
          println!("{}", ref1);
          println!("{}", ref2);
      }
    3. 문자열 슬라이스를 이용해 문장에서 첫 단어만 추출하는 함수를 완성하고, 테스트
    4. Move와 Copy가 각각 어떻게 다른지, 예시 코드를 작성해 GitHub에 올리기(가능하다면).

    학습 팁

    • Rust 컴파일러의 에러 메시지를 꼼꼼히 읽으면, Ownership & Borrowing에서 발생하는 문제를 빠르게 찾을 수 있음.
    • 문자열 슬라이스(&str)를 잘 활용하면, 데이터를 복사하지 않고도 특정 부분을 효율적으로 처리 가능.
    • 이 개념들을 이해해두면 이후에 Struct, Enum 등 더 복잡한 데이터 구조를 다룰 때 훨씬 수월해진다.

    5. 수업 진행 예시 타임라인 (총 50분 수업 기준)

    • 10분: 이론: 스택/힙, Ownership & Borrowing 개념 설명
    • 20분: 실습: Move/Copy, 참조 & 가변 참조, 슬라이스 예제 코딩 & 테스트
    • 10분: 에러 메시지 분석 및 디버깅(에러 예시 코드 함께 수정해보기)
    • 5분: 수업 정리, 질의응답
    • 5분: 과제 안내 및 마무리

    정리: Rust의 Ownership & Borrowing은 런타임에 비용을 추가하지 않고도 메모리 안전성을 보장하는 핵심 메커니즘입니다.

Designed by Tistory.