str (단독 사용 X)&str 형태로 사용됨.fn example(text: str) { // ❌ 오류: `str` 자체는 길이를 알 수 없음
println!("{}", text);
}
&str (문자열 슬라이스, 소유권 X, 불변)fn main() {
let msg = "Hello, Rust!"; // msg는 `&str`
println!("{}", msg);
}
"Hello, Rust!"는 프로그램 실행 중 변하지 않는 문자열 → &str 타입.String (소유권 있음, 가변 가능, 힙 저장)fn main() {
let mut s = String::from("Hello"); // 힙에 저장됨, 소유권 가짐
s.push_str(", Rust!"); // 가변이므로 수정 가능
println!("{}", s);
}
String::from("Hello") → 힙에 공간을 만들고 문자열을 저장함.push_str()으로 문자열을 수정할 수 있음.&String (String의 참조, 소유권 X, 불변)String을 참조하는 불변 참조(borrowed reference).&String을 받는 함수는 &str도 받을 수 있음 (Deref 변환).fn print_message(message: &String) {
println!("{}", message);
}
fn main() {
let s = String::from("Hello");
print_message(&s); // &String으로 전달
}
→ 하지만 대부분 &str이 더 유연함, 그래서 &String을 굳이 안 씀.
| 타입 | 저장 위치 | 소유권 (Ownership) | 가변성 (Mutable) | 사용 예시 |
|---|---|---|---|---|
str | ❌ 직접 사용 불가 | ❌ 없음 | ❌ 불변 | 직접 사용 ❌ |
&str | 스택 / 정적 메모리 | ❌ 없음 (borrow) | ❌ 불변 | "hello" (문자열 리터럴) |
String | 힙(Heap) | ✅ 있음 (owned) | ✅ 변경 가능 | String::from("hello") |
&String | 힙(Heap) | ❌ 없음 (borrow) | ❌ 불변 | &String::from("hello") |
&str, &String은 원본 데이터를 빌려온 것(borrow).String은 힙에 할당된 데이터를 직접 소유.String은 mut로 선언하면 수정 가능, &str은 불변.&str이 더 낫다.&String보다 &str이 낫냐?fn print_message(message: &str) { // &String이 아니라 &str이 더 유연함
println!("{}", message);
}
fn main() {
let name1 = "Alice"; // &str
let name2 = String::from("Bob"); // String
print_message(name1); // OK
print_message(&name2); // OK (`&String` → `&str` 자동 변환)
}
&str을 받으면 "Alice" (리터럴)도 받을 수 있고, &String도 받을 수 있음.&String보다 &str이 더 범용적이므로 보통 &str을 사용함."Hello") → &strString&str이 더 유연함 (&String 쓰지 말 것)