C.W.K.
Stream
Lesson 04 of 05 · published

슬라이스 — 조각을 빌리기

~11 min · borrowing, slices, str

Level 0Rust 호기심러
0 XP0/80 lessons0/19 achievements
0/100 XP to next level100 XP to go0% complete

슬라이스는 컬렉션의 연속된 조각 으로의 참조야 — 전체도 아니고, 복사본도 아니고, 그 일부로의 빌린 창문일 뿐이야.

문자열 슬라이스

&str 은 문자열 슬라이스야: 문자열 데이터로의 빌린 view. &s[0..5]String 의 첫 5바이트를 빌려. "hello" 같은 문자열 리터럴 자체가 &str 이야 — 컴파일된 바이너리를 가리키는 슬라이스. 이게 함수가 &str 을 받아야 하는 더 깊은 이유야: 리터럴이랑 빌린 String 둘 다 받거든.

배열과 벡터 슬라이스

같은 아이디어가 어떤 시퀀스에도 통해. &v[1..3] 은 벡터로의 창문을 빌려 — &[T] 타입 슬라이스. 슬라이스는 시작과 길이를 알아; 원소를 소유하지 않으니 가리키는 컬렉션보다 오래 못 살아. borrow checker 가 그걸 보장하고.

&String, &Vec 말고 &str, &[T] 를 받아. 슬라이스 형태가 더 일반적이야: `&str` 파라미터는 리터럴, 풀 String, 부분 문자열을 다 받아. 관용적 Rust 시그니처는 소유-컬렉션 참조 말고 슬라이스를 빌려.

왜 여기선 슬라이스가 안전하고 C 에선 위험하냐

C 에선 배열로의 포인터+길이가 터질 날만 기다리는 버그야 — 배열을 해제하면 포인터가 dangle 해. Rust 에선 슬라이스가 컬렉션을 빌리니까, borrow checker 가 슬라이스가 살아있는 동안 컬렉션이 drop 되거나 수정되게 안 둬. 같은 성능, 위험은 0.

Code

슬라이스는 복사가 아니라 창문을 빌린다·rust
fn first_word(s: &str) -> &str {
    let bytes = s.as_bytes();
    for (i, &b) in bytes.iter().enumerate() {
        if b == b' ' {
            return &s[0..i]; // 원본 문자열로의 슬라이스
        }
    }
    s
}

fn main() {
    let phrase = String::from("fearless concurrency");
    let word = first_word(&phrase); // &String 이 &str 로 coerce
    println!("{word}");             // fearless

    let nums = [10, 20, 30, 40];
    let middle = &nums[1..3];       // &[i32] 슬라이스
    println!("{middle:?}");         // [20, 30]
}

External links

Exercise

공백으로 구분된 첫 단어를 반환하는 fn first_word(s: &str) -> &str 를 써봐. String 으로도, 문자열 리터럴로도 호출해봐. 같은 함수가 네 쪽 변환 코드 없이 둘 다 통하는 이유가 뭐야?
Hint
&String&str 로 자동 coerce 되고, 리터럴은 이미 &str 이야. &str 을 받으면 시그니처 하나가 모든 종류의 문자열 입력을 처리해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고
💛 by 똘이warm

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.