Rust의 문자열 자료형은 &'static str 이다.
& : 메모리를 참조하고 있다
'static : 문자열 데이터가 프로그램이 끝날 때까지 유효(Drop 되지 않음)
str : 언제나 유효한 UTF-8 바이트 열
mut : 없으니 값의 변경을 허용하지 않음
Rust의 문자열은 언제나 유효
fn main() {
let a: &'static str = "Hi";
println!("{} {}", a, a.len());
}
fn main() {
let a: &'static str = r#"
<div class="advice">
Raw strings are ...
</div>
"#;
println!("{} {}", a, a.len());
}
시작점의 r# : 원시 문자열 지정, 덕분에 "advice"를 온전히 문자열의 일부로 해석
끝점의 # : 문자열을 있는 그대로 표현
fn main() {
let chars = "Hello!".chars().collect::<Vec<char>>();
println!("{}", chars.len());
println!("{}", chars[3] as u32);
}
Rust에서는 UTF-8 바이트 열을 char 타입의 벡터로 돌려주는 기능 제공.
char 하나는 4바이트다.
UTF-8 바이트 열을 힙 메모리에 소유하는 구조체
문자열과는 달리 변경 가능
fn main() {
let mut helloworld = String::from("hello");
helloworld.push_str(" world");
helloworld = helloworld + "!";
println!("{helloworld}");
}
문자열과 스트링은 일반적으로 함수에 문자열 슬라이스 형태로 전달.
이 방법은 소유권을 넘길 필요가 없어 대부분의 경우에 유연.
fn say_it(msg: &str) {
println!("{msg}");
}
fn main() {
say_it("hello");
say_it(&String::from("goodbye"));
}
concat 과 join은 스트링을 만드는 간단하지만 강력한 방법
fn main() {
let hello = ["hello", " ", "world", "!"].concat();
let abc = ["a", "b", "c"].join(",");
println!("{}", hello);
println!("{}", abc);
let s = concat!("test", 10, 'b', true);
assert_eq!(s, "test10btrue");
}
문자열 포맷도 인스터스화 가능
fn main() {
let a = 42;
let f = format!("secret to lilfe: {}", a);
println!("{}", f);
}
문자열 슬라이스는 메모리 상의 바이트 열에 대한 참조이다. String 처럼 문자열이 아니다
즉 &str이 바로 문자열 슬라이스이다.
문자열 슬라이스는 참조이기에 언제나 유효한 utf-8이어야 한다.
str slice의 문자열 slice (sub-slice)도 역시 유효한 utf-8이어야 합니다.
fn main() {
let a = "hi 🦀";
println!("{}", a.len());// 7 바이트
let first_word = &a[0..2];//'hi ' -> 3 바이트
let second_word = &a[3..7];'🦀' -> 4바이트
// let half_crab = &a[3..5]; 실패
// Rust는 유효하지 않은 유니코드 문자열의 slice를 허용하지 않습니다
println!("{} {}", first_word, second_word);
}
&str의 흔히 사용되는 메소드는 다음과 같다.
다른 언어에서는 정말 쉬운 문자열 인덱싱이 Rust에서는 굉장히 까다롭다.
문자열 인덱싱이 까다로운 이유는 고정된 문자 크기를 가지는 아스키가 아닌 가변적 문자 길이를 가지고 있는 UTF-8 이기 때문이다.
개발시 문자열 인덱싱은 가급적이면 사용하지 않는 편이 좋을 것이다.
그러나 문자열 인덱싱이 필요한 상황이라면 Vec<char>
로 변환 해서 사용
fn main() {
// 문자들을 char의 vector로 가져옵니다
let chars = "hi 🦀".chars().collect::<Vec<char>>();
println!("{}", chars.len()); // 4여야 합니다
// char가 4 바이트이므로 u32로 변환할 수 있습니다
println!("{}", chars[3] as u32);
}
문자열과 string은 일반적으로 함수에 문자열 slice 형태로 전달된다.
이 방법은 소유권을 넘길 필요가 없어 대부분의 경우에 유연성을 제공한다.
fn say_it_loud(msg: &str) {
println!("{}!!!", msg.to_string().to_uppercase());
}
fn main() {
// say_it_loud는 &'static str을 &str로 대여
say_it_loud("hello");
// say_it_loud는 또한 String을 &str로 대여
say_it_loud(&String::from("goodbye"));
}