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

문자열

Rust에서 가장 많이 사용되는 두 가지 문자열 타입은 String&str입니다.

String은 바이트 벡터(Vec<u8>)로 저장되지만, 항상 유효한 UTF-8 시퀀스임이 보장됩니다. String은 힙에 할당되며, 크기 조절이 가능하고 널 종료(null terminated)되지 않습니다.

&str은 항상 유효한 UTF-8 시퀀스를 가리키는 슬라이스(&[u8])이며, &[T]Vec<T>를 들여다보는 창(view)인 것과 마찬가지로 String을 들여다보는 데 사용될 수 있습니다.

fn main() {
    // (모든 타입 어노테이션은 불필요합니다)
    // 읽기 전용 메모리에 할당된 문자열에 대한 참조
    let pangram: &'static str = "the quick brown fox jumps over the lazy dog";
    println!("팬그램(Pangram): {}", pangram);

    // 단어들을 역순으로 순회합니다. 새로운 문자열은 할당되지 않습니다
    println!("역순 단어들");
    for word in pangram.split_whitespace().rev() {
        println!("> {}", word);
    }

    // 문자들을 벡터로 복사하고, 정렬한 뒤 중복을 제거합니다
    let mut chars: Vec<char> = pangram.chars().collect();
    chars.sort();
    chars.dedup();

    // 비어 있고 크기 조절 가능한 `String`을 생성합니다
    let mut string = String::new();
    for c in chars {
        // 문자열 끝에 문자를 삽입합니다
        string.push(c);
        // 문자열 끝에 문자열을 삽입합니다
        string.push_str(", ");
    }

    // 트림된 문자열은 원본 문자열에 대한 슬라이스이므로,
// 새로운 할당이 수행되지 않습니다
    let chars_to_trim: &[char] = &[' ', ','];
    let trimmed_str: &str = string.trim_matches(chars_to_trim);
    println!("사용된 문자들: {}", trimmed_str);

    // 문자열을 힙에 할당합니다
    let alice = String::from("I like dogs");
    // 새로운 메모리를 할당하고 수정된 문자열을 그곳에 저장합니다
    let bob: String = alice.replace("dog", "cat");

    println!("앨리스가 말합니다: {}", alice);
    println!("밥이 말합니다: {}", bob);
}

더 많은 str/String 메서드는 std::strstd::string 모듈에서 찾을 수 있습니다

리터럴과 이스케이프

특수 문자가 포함된 문자열 리터럴을 작성하는 방법은 여러 가지가 있습니다. 모두 비슷한 &str을 결과로 내므로 가장 작성하기 편리한 형식을 사용하는 것이 좋습니다. 마찬가지로 바이트 문자열 리터럴을 작성하는 방법도 여러 가지가 있으며, 모두 &[u8; N] 결과를 냅니다.

일반적으로 특수 문자는 백슬래시 문자 \로 이스케이프됩니다. 이 방법을 통해 출력 불가능한 문자나 입력 방법을 모르는 문자 등 어떤 문자든 문자열에 추가할 수 있습니다. 백슬래시 자체를 리터럴로 원한다면 백슬래시 하나를 더 붙여 \\와 같이 이스케이프하세요.

리터럴 내에 나타나는 문자열 또는 문자 리터럴 구분자는 반드시 이스케이프해야 합니다: "\"", '\''.

fn main() {
    // 16진수 값을 사용하여 바이트를 작성하기 위해 이스케이프를 사용할 수 있습니다...
    let byte_escape = "I'm writing \x52\x75\x73\x74!";
    println!("What are you doing\x3F (\\x3F는 ?를 의미합니다) {}", byte_escape);

    // ...또는 유니코드 코드 포인트.
    let unicode_codepoint = "\u{211D}";
    let character_name = "\"DOUBLE-STRUCK CAPITAL R\"";

    println!("유니코드 문자 {} (U+211D)는 {}라고 불립니다",
                unicode_codepoint, character_name );


    let long_string = "문자열 리터럴은
                        여러 줄에 걸쳐 있을 수 있습니다.
                        여기서의 줄바꿈과 들여쓰기 ->\
                        <- 역시 이스케이프될 수 있습니다!";
    println!("{}", long_string);
}

때때로 이스케이프해야 할 문자가 너무 많거나 문자열을 있는 그대로 작성하는 것이 훨씬 더 편리할 때가 있습니다. 이때 로우(raw) 문자열 리터럴이 사용됩니다.

fn main() {
    let raw_str = r"이스케이프가 여기선 작동하지 않습니다: \x3F \u{211D}";
    println!("{}", raw_str);

    // 로우 문자열에서 따옴표가 필요하다면, # 쌍을 추가하세요
    let quotes = r#"And then I said: "There is no escape!""#;
    println!("{}", quotes);

    // 문자열 내에 "#가 필요하다면, 구분자에 더 많은 #를 사용하세요.
    // 최대 255개의 #를 사용할 수 있습니다.
    let longer_delimiter = r###"A string with "# in it. And even "##!"###;
    println!("{}", longer_delimiter);
}

UTF-8이 아닌 문자열을 원하시나요? (strString은 반드시 유효한 UTF-8이어야 함을 기억하세요). 아니면 대부분이 텍스트인 바이트 배열을 원하시나요? 바이트 문자열이 해결해 드립니다!

use std::str;

fn main() {
    // 이는 실제로 `&str`이 아님에 유의하세요
    let bytestring: &[u8; 21] = b"this is a byte string";

    // 바이트 배열은 `Display` 트레이트를 가지고 있지 않으므로, 출력에 다소 제한이 있습니다
    println!("바이트 문자열: {:?}", bytestring);

    // 바이트 문자열은 바이트 이스케이프를 가질 수 있습니다...
    let escaped = b"\x52\x75\x73\x74 as bytes";
    // ...하지만 유니코드 이스케이프는 허용되지 않습니다
    // let escaped = b"\u{211D} is not allowed";
    println!("일부 이스케이프된 바이트: {:?}", escaped);


    // 로우 바이트 문자열은 로우 문자열과 똑같이 작동합니다
    let raw_bytestring = br"\u{211D} is not escaped here";
    println!("{:?}", raw_bytestring);

    // 바이트 배열을 `str`로 변환하는 것은 실패할 수 있습니다
    if let Ok(my_str) = str::from_utf8(raw_bytestring) {
        println!("그리고 텍스트로 변환하면: '{}'", my_str);
    }

    let _quotes = br#"일반 로우 문자열처럼, \
                    더 "화려한" 포맷팅을 사용할 수도 있습니다"#;

    // 바이트 문자열은 UTF-8일 필요가 없습니다
    let shift_jis = b"\x82\xe6\x82\xa8\x82\xb1\x82\xbb"; // SHIFT-JIS 인코딩의 "ようこそ"(환영합니다)

    // 그런 경우에는 항상 `str`로 변환될 수는 없습니다
    match str::from_utf8(shift_jis) {
        Ok(my_str) => println!("변환 성공: '{}'", my_str),
        Err(e) => println!("변환 실패: {:?}", e),
    };
}

문자 인코딩 간의 변환에 대해서는 encoding 크레이트를 확인해 보세요.

문자열 리터럴을 작성하고 문자를 이스케이프하는 방법에 대한 더 자세한 목록은 Rust 레퍼런스의 ‘Tokens’ 장에 나와 있습니다.