Rust 문자열
텍스트를 다루는 부분은 Rust가 다른 언어와 다르다고 처음 느끼게 되는 곳 중 하나예요. 가장 큰 이유는 Rust에 문자열 타입이 두 가지나 있기 때문이에요. 왜 그런지 알고 나면 더는 헷갈리지 않아요.
&str과 String
섹션 제목: “&str과 String”&str(“문자열 슬라이스”) - 이미 어딘가에 있는 텍스트예요. 보통 코드에 직접 적어 넣은 텍스트가 여기에 해당해요. 크기가 고정되어 있어서 늘릴 수 없어요.String- 소유권(ownership)을 가진, 늘릴 수 있는 텍스트예요. 내용을 덧붙일 수 있고, 힙(heap)에 저장돼요.
fn main() { let literal: &str = "안녕"; // 문자열 슬라이스 let owned: String = String::from("안녕"); // 소유권을 가진 String
println!("{literal} / {owned}");}간단한 기준을 하나 알려 드릴게요. 고정된 텍스트를 출력하기만 한다면 "이렇게" 쓰는 것(&str)으로 충분해요. 실행 중에 텍스트를 만들거나, 늘리거나, 고쳐야 한다면 String을 쓰세요.
String 늘리기
섹션 제목: “String 늘리기”fn main() { let mut greeting = String::from("안녕하세요"); greeting.push_str(", 세상"); // &str 덧붙이기 greeting.push('!'); // 문자 하나 덧붙이기
println!("{greeting}");}실행 결과:
안녕하세요, 세상!문자열 합치기
섹션 제목: “문자열 합치기”문자열은 +로 합칠 수도 있고, format!을 쓸 수도 있어요. 보통은 format! 쪽이 더 읽기 쉬워요.
fn main() { let first = String::from("안녕하세요, "); let second = String::from("세상!");
let combined = first + &second; // second 앞의 &에 주목하세요 println!("{combined}");
// format!이 더 읽기 쉬울 때가 많아요. let name = "Ferris"; let greeting = format!("안녕하세요, {name}!"); println!("{greeting}");}유용한 문자열 메서드
섹션 제목: “유용한 문자열 메서드”자주 쓰게 될 메서드 몇 가지예요. 이 예제는 .len()으로 바이트 수를 세기 때문에 문자열을 영어로 두었어요. 한글은 한 글자가 UTF-8로 3바이트라서 결과가 달라지거든요.
fn main() { let text = " Hello, Rust! ";
println!("{}", text.trim()); // "Hello, Rust!" (앞뒤 공백 없음) println!("{}", text.to_uppercase()); // " HELLO, RUST! " println!("{}", text.to_lowercase()); // " hello, rust! " println!("{}", text.contains("Rust")); // true println!("{}", text.trim().len()); // 12 (바이트 단위 길이) println!("{}", text.trim().replace("Rust", "World")); // "Hello, World!"}문자열을 한 글자씩 살펴보기
섹션 제목: “문자열을 한 글자씩 살펴보기”문자를 하나씩 살펴보려면 .chars()를 쓰세요.
fn main() { for c in "abc".chars() { println!("{c}"); }}연습 문제
섹션 제목: “연습 문제”1. 지저분한 입력 정리하기
섹션 제목: “1. 지저분한 입력 정리하기”누군가 입력 양식에 " rUsT is FUN "이라고 적었어요. 이것을 rust is great로 바꿔 보세요. 앞뒤 공백을 없애고, 모두 소문자로 바꾸고, fun을 great로 바꾸면 돼요. 그리고 결과와 그 길이를 출력하세요. 힌트: 문자열 메서드는 text.trim().to_lowercase()...처럼 줄줄이 이어서 호출할 수 있어요.
정답 보기
fn main() { let input = " rUsT is FUN ";
// 먼저 trim, 그다음 소문자로, 그다음 (이제 소문자가 된) "fun"을 바꿔요 let clean = input.trim().to_lowercase().replace("fun", "great");
println!("{clean}"); println!("{}바이트", clean.len());}실행 결과:
rust is great13바이트순서가 중요해요. .to_lowercase()보다 .replace("fun", "great")를 먼저 호출하면 아무것도 바뀌지 않아요. 그 시점에는 텍스트가 아직 FUN이기 때문이에요.
2. 이메일 주소 만들기
섹션 제목: “2. 이메일 주소 만들기”first = "Ada"와 last = "Lovelace"가 주어졌을 때, [email protected]이라는 String을 만들어 출력하세요. 그다음 그 안에 @가 들어 있는지도 출력하세요. 힌트: format!의 {} 자리에는 first.to_lowercase() 같은 식을 인자로 넣을 수 있어요.
정답 보기
fn main() { let first = "Ada"; let last = "Lovelace";
let email = format!("{}.{}@example.com", first.to_lowercase(), last.to_lowercase());
println!("{email}"); println!("올바른 형식인가요: {}", email.contains('@'));}실행 결과:
올바른 형식인가요: true&str은 빌려 온 고정된 텍스트이고,String은 소유권을 가지며 늘릴 수 있어요.String은.push_str()(텍스트)이나.push()(문자 하나)로 늘려요.- 문자열을 합칠 때는
+보다format!을 쓰세요. 더 읽기 쉽고 아무것도 이동시키지 않아요. - 자주 쓰는 메서드:
.trim(),.to_uppercase(),.contains(),.replace(),.chars().
이해도 점검
섹션 제목: “이해도 점검”이해도 점검
1. 소유권을 가지고, 실행 중에 늘릴 수 있는 문자열 타입은 무엇인가요?
2. 여러 문자열을 합칠 때 이 페이지에서 +보다 format!을 권하는 이유는 무엇인가요?
3. Rust 문자열을 text[0]처럼 인덱싱할 수 없는 이유는 무엇인가요?
4. greeting.push('!')처럼 String에 문자 하나를 덧붙이는 메서드는 무엇인가요?
점수: 0 / 4
더 알아보기
섹션 제목: “더 알아보기”- 문자열에 UTF-8 텍스트 저장하기 - The Rust Programming Language 한국어판: 위치로 인덱싱할 수 없는 이유까지 포함해
String을 다루는 공식 문서의 장이에요. - 슬라이스 - The Rust Programming Language 한국어판: 대여(borrowing)를 배우고 나서 읽으면
&str이 정확히 무엇인지 알 수 있어요. - Strings - Rust by Example (영어):
String과&str, 이스케이프 문자, 원시 문자열(raw string)을 실행 가능한 예제로 보여 줘요. String- 표준 라이브러리 문서 (영어): 소유권을 가진String의 모든 메서드를 작은 예제와 함께 볼 수 있어요.str- 표준 라이브러리 문서 (영어): 어떤 텍스트에든 쓸 수 있는trim,contains,replace,split같은 메서드가 나와 있어요.