이번 편의 목표: 한글 제목의 바이트 수와 글자 수를 구분하고, 첫 단어만 참조로 꺼냅니다.

String은 소유하는 문자열입니다. &str은 그 문자열의 일부 또는 전체를 빌린 슬라이스입니다. len은 바이트 수입니다. 한글 한 글자는 UTF-8에서 3바이트이므로 글자 수와 다릅니다. 글자 수는 chars().count()로 셉니다.

Rust
fn first_word(title: &str) -> &str {
    for (index, ch) in title.char_indices() {
        if ch == ' ' {
            return &title[..index];
        }
    }
    title
}

fn main() {
    let title = String::from("생각 나무");
    println!("{}", title.len());
    println!("{}", title.chars().count());
    let word = first_word(&title);
    println!("{word}");
}

생각과 나무, 그리고 가운데 공백은 3바이트짜리 글자 둘과 1바이트 공백입니다. 첫 줄은 13, 둘째 줄은 5, 셋째 줄은 생각입니다. char_indices의 index는 바이트 위치이므로, 그 위치에서 자르면 글자 중간을 가르지 않습니다. 정수 인덱스로 한글을 임의로 자르면 패닉이 날 수 있습니다.

함수가 &str을 받으면 String과 문자열 리터럴을 모두 넘길 수 있습니다. String을 넘길 때는 &title처럼 빌립니다. 첫 단어를 새 String으로 복사하지 않고, title이 살아있는 동안만 유효한 참조로 돌려줍니다.

직접 해 보기

제목을 나무 생각으로 바꿨을 때 마지막 줄이 나무인지 확인하세요.

해설

첫 공백 앞이 나무이므로 first_word의 결과는 나무입니다. 바이트 길이는 공백 위치만 달라질 뿐 글자 구성은 같아 13입니다. 글자 수는 5입니다.