홈강좌Rust 입문·중급 47편 중 20편째
Rust String 과 &str — 가진 문자열과 빌린 문자열
Rust 문자열은 둘이다. String 은 늘이고 고칠 수 있는 가진 문자열이고, &str 은 어딘가에 있는 글자를 빌려 보는 문자열이다. 큰따옴표로 쓴 글자는 &str 이라서 String 자리에 넣으면 E0308 이 난다. .to_string() 이나 String::from 으로 바꾼다. 문자열을 받는 함수는 &str 로 받으면 둘 다 받을 수 있다.
01 큰따옴표로 쓴 글자는 &str 이다
1편부터 써 온 "Hello, world!" 같은 글자의 타입은 String 이 아니다. String 이라고 적은 변수에 넣어 보자.
fn main() {
let name: String = "ferris";
println!("{name}");
}error[E0308]: mismatched types
--> src/main.rs:2:24
|
2 | let name: String = "ferris";
| ------ ^^^^^^^^ expected `String`, found `&str`
| |
| expected due to this
|
help: try using a conversion method
|
2 | let name: String = "ferris".to_string();
| ++++++++++++- 무엇 — 타입이 안 맞는다.
- 어디 — 2번째 줄의
"ferris".String이 와야 하는데&str이 왔다. - 고치는 법 —
help:가 바꾸는 메서드(conversion method).to_string()을 붙이라고 한다.
"ferris" 같은 글자는 프로그램 파일 안에 박혀 있다. 변수는 그 글자를 빌려 볼 뿐이라 타입이 &str 이다. 18편의 & 가 바로 이 & 다. 빌린 것이니 늘이거나 고칠 수 없다.
02 String 은 늘이고 고칠 수 있다
String 은 자기 글자를 직접 가진 문자열이다. 15편부터 쓴 String::from(…) 이 &str 의 글자를 복사해 String 을 만든다.
fn main() {
let fixed = "hello";
let mut owned = String::from("hello");
owned.push_str(", world");
let also = "ferris".to_string();
let joined = format!("{owned} and {also}");
println!("{fixed}");
println!("{owned}");
println!("{joined}");
} Compiling text v0.1.0 (~/projects/text)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.19s
Running `target/debug/text`
hello
hello, world
hello, world and ferrispush_str은 뒤에 글자를 덧붙인다. 고치는 것이니let mut다..to_string()은String::from과 같은 일을 한다. 편한 쪽을 쓴다.format!은println!과 같은 모양으로 쓰는데, 찍는 대신 그 결과를String으로 돌려준다. 문자열을 이어 붙일 때 가장 쉽다.
String | &str | |
|---|---|---|
| 뜻 | 가진 문자열 | 빌린 문자열 |
| 만들기 | String::from("…") · "…".to_string() · format! | "…" 그대로 · &내_String |
| 고치기 | let mut 이면 된다 | 안 된다 |
03 실습 — 문자열을 받는 함수는 &str 로
10편의 greet(name: &str) 를 다시 보자. 이제 왜 &str 인지 알 수 있다.
fn greet(name: &str) {
println!("Hello, {name}!");
}
fn main() {
let owned = String::from("Ferris");
greet(&owned);
greet("Rust");
} Compiling greet v0.1.0 (~/projects/greet)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.18s
Running `target/debug/greet`
Hello, Ferris!
Hello, Rust!greet(&owned) 는 String 을 빌려준 것이고, greet("Rust") 는 처음부터 &str 이다. 둘 다 받아졌다. &String 을 &str 자리에 넘기면 Rust 가 알아서 &str 로 맞춰 준다. 그래서 문자열을 읽기만 하는 함수는 매개변수를 &str 로 두는 것이 관례다. 18편의 length(text: &String) 도 &str 로 바꾸는 편이 낫다.
greet(owned) 처럼 & 없이 넘겨 보자. String 을 넘긴 것이니 타입이 안 맞는다는 오류가 난다. 다음 편에서는 문자열의 일부만 빌리는 슬라이스와, 한글을 자를 때의 함정을 다룬다.