Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

배열과 슬라이스

배열은 연속된 메모리에 저장된 동일한 타입 T를 가진 객체들의 모음입니다. 배열은 대괄호 []를 사용하여 생성되며, 컴파일 타임에 알려진 배열의 길이는 타입 시그니처 [T; length]의 일부가 됩니다.

슬라이스는 배열과 유사하지만, 컴파일 타임에 그 길이를 알 수 없습니다. 대신, 슬라이스는 두 개의 워드(word)로 구성된 객체입니다. 첫 번째 워드는 데이터에 대한 포인터이고, 두 번째 워드는 슬라이스의 길이입니다. 워드 크기는 프로세서 아키텍처에 의해 결정되는 usize와 같으며, 예를 들어 x86-64에서는 64비트입니다. 슬라이스는 배열의 일부분을 빌려오는 데 사용될 수 있으며 &[T]라는 타입 시그니처를 가집니다.

use std::mem;

// 이 함수는 슬라이스를 빌려옵니다.
fn analyze_slice(slice: &[i32]) {
    println!("슬라이스의 첫 번째 요소: {}", slice[0]);
    println!("슬라이스는 {}개의 요소를 가지고 있습니다", slice.len());
}

fn main() {
    // 고정 크기 배열 (타입 시그니처는 생략 가능합니다).
    let xs: [i32; 5] = [1, 2, 3, 4, 5];

    // 모든 요소를 동일한 값으로 초기화할 수 있습니다.
    let ys: [i32; 500] = [0; 500];

    // 인덱싱은 0부터 시작합니다.
    println!("배열의 첫 번째 요소: {}", xs[0]);
    println!("배열의 두 번째 요소: {}", xs[1]);

    // `len`은 배열의 요소 개수를 반환합니다.
    println!("배열의 요소 개수: {}", xs.len());

    // 배열은 스택에 할당됩니다.
    println!("배열의 점유 메모리: {} 바이트", mem::size_of_val(&xs));

    // 배열은 자동으로 슬라이스로 빌려올 수 있습니다.
    println!("배열 전체를 슬라이스로 빌려옵니다.");
    analyze_slice(&xs);

    // 슬라이스는 배열의 한 섹션을 가리킬 수 있습니다.
    // [시작_인덱스..종료_인덱스] 형태입니다.
    // `시작_인덱스`는 슬라이스의 첫 번째 위치입니다.
    // `종료_인덱스`는 슬라이스의 마지막 위치보다 하나 더 큰 값입니다.
    println!("배열의 한 섹션을 슬라이스로 빌려옵니다.");
    analyze_slice(&ys[1 .. 4]);

    // 빈 슬라이스 `&[]`의 예시:
    let empty_array: [u32; 0] = [];
    assert_eq!(&empty_array, &[]);
    assert_eq!(&empty_array, &[][..]); // 동일하지만 더 장황한 표현

    // 배열은 `.get`을 사용하여 안전하게 접근할 수 있으며, 이는 `Option`을 반환합니다.
    // 이는 아래와 같이 매치(match)될 수 있으며, 프로그램을 계속 진행하는 대신
    // 친절한 메시지와 함께 종료하고 싶다면 `.expect()`와 함께 사용될 수 있습니다.
    for i in 0..xs.len() + 1 { // 이런, 범위를 하나 벗어났네요!
        match xs.get(i) {
            Some(xval) => println!("{}: {}", i, xval),
            None => println!("진정하세요! {}는 너무 멀리 갔습니다!", i),
        }
    }

    // 상수 값을 사용한 배열의 범위를 벗어난 인덱싱은 컴파일 타임 에러를 발생시킵니다.
    //println!("{}", xs[5]);
    // 슬라이스에서 범위를 벗어난 인덱싱은 런타임 에러를 발생시킵니다.
    //println!("{}", xs[..][5]);
}