hyunsu blog

홈강좌Rust 입문·중급 47편 중 20편째

Rust String 과 &str — 가진 문자열과 빌린 문자열

목차 · 3
  1. 01큰따옴표로 쓴 글자는 &str 이다
  2. 02String 은 늘이고 고칠 수 있다
  3. 03실습 — 문자열을 받는 함수는 &str 로

Rust 문자열은 둘이다. String 은 늘이고 고칠 수 있는 가진 문자열이고, &str 은 어딘가에 있는 글자를 빌려 보는 문자열이다. 큰따옴표로 쓴 글자는 &str 이라서 String 자리에 넣으면 E0308 이 난다. .to_string() 이나 String::from 으로 바꾼다. 문자열을 받는 함수는 &str 로 받으면 둘 다 받을 수 있다.

01 큰따옴표로 쓴 글자는 &str 이다

1편부터 써 온 "Hello, world!" 같은 글자의 타입은 String 이 아니다. String 이라고 적은 변수에 넣어 보자.

rust
fn main() {
    let name: String = "ferris";
    println!("{name}");
}
text
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();
  |                                ++++++++++++
  1. 무엇 — 타입이 안 맞는다.
  2. 어디 — 2번째 줄의 "ferris". String 이 와야 하는데 &str 이 왔다.
  3. 고치는 법 — help: 가 바꾸는 메서드(conversion method) .to_string() 을 붙이라고 한다.

"ferris" 같은 글자는 프로그램 파일 안에 박혀 있다. 변수는 그 글자를 빌려 볼 뿐이라 타입이 &str 이다. 18편의 & 가 바로 이 & 다. 빌린 것이니 늘이거나 고칠 수 없다.

02 String 은 늘이고 고칠 수 있다

String 은 자기 글자를 직접 가진 문자열이다. 15편부터 쓴 String::from(…) 이 &str 의 글자를 복사해 String 을 만든다.

rust
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}");
}
text
   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 ferris
  • push_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 인지 알 수 있다.

rust
fn greet(name: &str) {
    println!("Hello, {name}!");
}

fn main() {
    let owned = String::from("Ferris");
    greet(&owned);
    greet("Rust");
}
text
   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 을 넘긴 것이니 타입이 안 맞는다는 오류가 난다. 다음 편에서는 문자열의 일부만 빌리는 슬라이스와, 한글을 자를 때의 함정을 다룬다.