본문 바로가기

Rust

슬라이스

[1. 개요]

슬라이스는 소유권을 갖지 않는 데이터 타입이다.

 

컬렉션의 연속된 일련의 요소들을 참조 할 수 있게 한다.

 

String::as_bytes().iter().enumerate() => (index, &item)

 

 

[2. string slice]

 

범위는 다음과 같다. [start, end)

let s = String::from("hello world");

let hello = &s[0..5];
let world = &s[6..11];

아래와 같이 slice 범위를 정할 수 있다.

 

[start..end]

[..end]

[start..]

[..]

 

fn first_word(s: &String) -> &str {
    let bytes = s.as_bytes();

    for (i, &item) in bytes.iter().enumerate() {
        if item == b' ' {
            return &s[0..i];
        }
    }

    &s[..]
}

 

함수 인자로 참조자 전달 후, 반환 값을 사용했을 때,

원본 String 메모리 해제가 먼저 발생하는 경우 컴파일 에러가 발생한다.

=> clear() 등을 이용해서 힙 소유권을 반납하지는 않지만, 힙 데이터 변경 등이 발생하는 경우,

     불변참조자는 문제가 되나, 가변참조자는 문제가 되지 않는다.

 

 

스트링 리터럴은 슬라이스 이다.

=> 타입이 &str 이다.

=> 불변참조자이다.

 

위 함수는 다음과 같이 작성 할수도 있다.

fn first_word(s: &str) -> &str {
    let bytes = s.as_bytes();

    for (i, &item) in bytes.iter().enumerate() {
        if item == b' ' {
            return &s[0..i];
        }
    }

    &s[..]
}

 

String 참조자 대신, string slice 를 넘길 수 도 있다.

 

fn main() {
    let my_string = String::from("hello world");

    // first_word가 `String`의 슬라이스로 동작합니다.
    let word = first_word(&my_string[..]);

    let my_string_literal = "hello world";

    // first_word가 스트링 리터럴의 슬라이스로 동작합니다.
    let word = first_word(&my_string_literal[..]);

    // 스트링 리터럴은 *또한* 스트링 슬라이스이기 때문에,
    // 아래 코드도 슬라이스 문법 없이 동작합니다!
    let word = first_word(my_string_literal);
}

 

 

배열도 slice 화 할 수 있다.

'Rust' 카테고리의 다른 글

Rust 열거형과 패턴 매칭  (0) 2022.08.20
Rust 구조체  (0) 2022.08.20
참조자와 빌림  (0) 2022.08.18
소유권  (0) 2022.08.17
함수와 제어문  (0) 2022.08.17