배열, 슬라이스

배열은 메모리에 연속적으로 저장된 동일한 T 타입 요소의 집합입니다. 배열은 대괄호 []를 사용해 생성하며, 타입 시그니처 [T; length]의 일부인 배열 길이는 컴파일 타임에 알 수 있습니다.

슬라이스는 배열과 유사하지만, 슬라이스의 길이는 컴파일 타임에 알 수 없습니다. 슬라이스는 두 개의 word로 구성됩니다. 첫 번째 word는 데이터의 포인터이고, 두 번째 word는 슬라이스의 길이입니다. word 크기는 usize 크기와 동일하게 프로세서 아키텍처(x86-64의 경우 64비트)에 의해 결정됩니다. 슬라이스는 배열의 일부를 borrow 하는 데에 사용할 수 있습니다. (타입 시그니처는 &[T]입니다.)

use std::mem;

// 슬라이스를 borrow 하는 함수
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));

    // 배열은 자동으로 슬라이스로 borrow 될 수 있습니다.
    println!("전체 배열을 슬라이스로 borrow 합니다");
    analyze_slice(&xs);

    // 슬라이스는 [시작_인덱스..끝_인덱스] 형태로
    // 배열의 일부를 가리킬 수 있습니다.
    // 시작_인덱스는 슬라이스에 포함할 첫 번째 요소의 위치이고,
    // 끝_인덱스는 슬라이스에 포함할 마지막 위치에 1을 더한 위치입니다.
    println!("배열의 일부를 슬라이스로 borrow 합니다");
    analyze_slice(&ys[1 .. 4]);

    // 인덱싱이 범위를 벗어나면 컴파일 에러가 발생합니다.
    println!("{}", xs[5]);
}