Rust에서 String을 반복(iteration)하거나 문자(char) 단위로 접근하는 방법은 몇 가지가 있습니다. Rust의 String은 UTF-8로 인코딩된 가변 길이 문자열을 저장하기 때문에 문자나 바이트에 접근하는 방식에 따라 다르게 처리해야 합니다. 아래에서는 다양한 접근과 반복 방법들을 소개합니다.
1. 문자(char) 단위로 반복
Rust의 String은 UTF-8로 인코딩되어 있기 때문에, 문자열을 문자(char) 단위로 접근하려면 .chars() 메서드를 사용해야 합니다.
rust
코드 복사
fn main() {
let text = String::from("Hello, Rust!");
// 문자 단위로 반복
for c in text.chars() {
println!("{}", c);
}
}
- chars(): 문자열을 문자(char) 단위로 분리합니다.
- 예를 들어, "Hello, Rust!"의 각 문자는 H, e, l, l, o, , 등이 됩니다.
2. 바이트(byte) 단위로 반복
String을 바이트(byte) 단위로 반복하고 싶을 때는 .bytes() 메서드를 사용합니다.
rust
코드 복사
fn main() {
let text = String::from("Hello, Rust!");
// 바이트 단위로 반복
for byte in text.bytes() {
println!("{}", byte);
}
}
- bytes(): 각 문자를 UTF-8 인코딩된 바이트로 반환합니다.
- "Hello, Rust!"의 첫 문자인 H는 바이트 값으로 72가 됩니다.
3. 인덱스로 접근 (슬라이싱)
Rust에서는 문자열을 슬라이싱할 수 있습니다. 하지만 Rust의 String은 UTF-8로 인코딩되어 있기 때문에, 잘못된 인덱스로 접근하면 런타임 에러가 발생할 수 있습니다. 문자열을 슬라이스할 때는 반드시 유효한 UTF-8 경계를 사용해야 합니다.
rust
코드 복사
fn main() {
let text = String::from("Hello, Rust!");
// 문자열 슬라이스로 접근
let slice = &text[0..5];
println!("{}", slice); // "Hello"
}
- [0..5]: 문자열의 0부터 5 이전까지 슬라이스합니다. 즉, "Hello"를 추출합니다.
- 주의: 슬라이스 인덱스는 반드시 문자 경계를 따라야 합니다. 그렇지 않으면 panic이 발생합니다.
rust
코드 복사
fn main() {
let text = String::from("안녕하세요");
// 잘못된 UTF-8 경계를 슬라이스하면 런타임 에러 발생
// let slice = &text[0..3]; // panic! 발생
}
4. 문자 인덱스로 접근하기 (nth 메서드)
chars().nth(index) 메서드를 사용하면 특정 인덱스에 있는 문자를 가져올 수 있습니다.
rust
코드 복사
fn main() {
let text = String::from("Hello, Rust!");
// 4번째 문자 가져오기 (인덱스는 0부터 시작)
if let Some(ch) = text.chars().nth(4) {
println!("4번째 문자는: {}", ch); // "o"
}
}
- nth(): 문자열의 n번째 문자를 가져옵니다. 만약 인덱스가 범위를 벗어나면 **None*을 반환합니다.
- 반환값이 **Option<char>*이기 때문에 if let이나 match를 사용해 안전하게 처리합니다.
5. 반복자(iterator) 사용해 문자 수정
문자열을 반복하면서 특정 조건에 따라 수정된 문자열을 만들고 싶을 때는 **chars()와 map()**을 사용할 수 있습니다.
rust
코드 복사
fn main() {
let text = String::from("Hello, Rust!");
// 모든 소문자를 대문자로 변환
let uppercased: String = text.chars()
.map(|c| c.to_ascii_uppercase())
.collect();
println!("{}", uppercased); // "HELLO, RUST!"
}
- map(): 각 문자를 변환합니다. 여기서는 to_ascii_uppercase()를 사용해 대문자로 변환했습니다.
- collect(): 반복자에서 새 문자열을 만듭니다.
6. 문자열을 역순으로 반복
문자열을 역순으로 반복하고 싶다면 chars().rev() 메서드를 사용합니다.
rust
코드 복사
fn main() {
let text = String::from("Hello, Rust!");
// 역순으로 출력
for c in text.chars().rev() {
print!("{}", c);
}
println!(); // "tsuR ,olleH"
}
- rev(): 반복자를 역순으로 만듭니다.
- 이 코드는 "Hello, Rust!"를 뒤집어서 출력합니다.
7. 문자열 길이 구하기
문자열의 문자 개수나 바이트 길이를 구하려면 각각 .chars().count()와 .len() 메서드를 사용할 수 있습니다.
rust
코드 복사
fn main() {
let text = String::from("안녕하세요");
// 문자 개수와 바이트 길이
println!("문자 개수: {}", text.chars().count()); // 5
println!("바이트 길이: {}", text.len()); // 15
}
- .chars().count(): 유니코드 문자 수를 셉니다.
- .len(): 바이트 단위 길이를 반환합니다. 안녕하세요는 UTF-8에서 3바이트씩 5개의 문자를 사용하므로 총 15바이트입니다.
8. 부분 문자열 찾기
부분 문자열이 포함되어 있는지 확인하려면 .contains() 메서드를 사용할 수 있습니다.
rust
코드 복사
fn main() {
let text = String::from("The Rust Programming Language");
// 부분 문자열 확인
if text.contains("Rust") {
println!("'Rust'가 포함되어 있습니다!");
}
}
- contains(): 문자열에 특정 부분 문자열이 포함되어 있는지 확인합니다.
9. 문자열을 다른 문자열로 대체하기
replace() 메서드를 사용하면 문자열의 일부를 다른 문자열로 대체할 수 있습니다.
rust
코드 복사
fn main() {
let text = String::from("I love Rust!");
// "Rust"를 "Rust programming"으로 대체
let new_text = text.replace("Rust", "Rust programming");
println!("{}", new_text); // "I love Rust programming!"
}
10. 요약
- chars(): 문자 단위로 반복.
- bytes(): 바이트 단위로 반복.
- 슬라이싱: [start..end]로 문자열 일부에 접근 (UTF-8 경계 주의!).
- nth(): n번째 문자에 접근.
- map()과 collect(): 문자 변환 후 새 문자열 생성.
- rev(): 문자열 역순 반복.
- contains(): 부분 문자열 검색.
- replace(): 문자열 일부 대체.