본문 바로가기
Programming/Rust

Rust 에서 String에 대한 참조자 대신에 문자열 슬라이스를 매개변수로 하는 함수를 정의하는 것이 좋은 설계인 이유

by 가우리언 2025. 11. 14.
728x90
반응형

왜 문자열 슬라이스(&str)가 더 나은가?

1. 더 넓은 호환성

fn process_text(text: &str) -> usize {
    text.len()
}

// 다음과 같은 모든 경우에 사용 가능
fn main() {
    let string_value = String::from("Hello");
    let string_literal = "World";
    let string_slice = &string_value[0..3]; // "Hel"

    process_text(&string_value);    // String 참조
    process_text(string_literal);   // 문자열 리터럴
    process_text(string_slice);     // 문자열 슬라이스
    process_text("Direct literal"); // 직접 리터럴
}

2. 불필요한 할당 방지

// 나쁜 예: String 참조만 받음
fn bad_function(text: &String) {
    println!("{}", text);
}

// 좋은 예: 모든 문자열 타입 받음
fn good_function(text: &str) {
    println!("{}", text);
}

fn main() {
    let my_string = String::from("hello");

    bad_function(&my_string);  // OK
    // bad_function("hello");  // 컴파일 에러!

    good_function(&my_string); // OK
    good_function("hello");    // OK
}

3. 성능 향상

&str은 문자열 데이터에 대한 참조만 포함하지만, &String은 String 구조체 전체에 대한 참조입니다.

언제 &String을 사용해야 하나?

1. String의 메서드를 직접 사용해야 할 때

fn modify_string(s: &mut String) {
    s.push_str(" world!"); // String의 메서드 사용
}

fn reserve_capacity(s: &String) -> usize {
    s.capacity() // String 전용 메서드
}

2. API가 String 소유권을 필요로 할 때

struct TextContainer {
    content: String,
}

impl TextContainer {
    // 소유권이 필요하므로 String을 받음
    fn new(content: String) -> Self {
        Self { content }
    }

    // 내부 데이터를 수정해야 하므로 &mut String
    fn clear(&mut self) {
        self.content.clear();
    }
}

실용적인 예제

// 좋은 설계: &str 사용
fn find_word(haystack: &str, needle: &str) -> Option<usize> {
    haystack.find(needle)
}

// 필요할 때만 String 사용
fn create_greeting(name: &str) -> String {
    format!("Hello, {}!", name)
}

fn main() {
    let text = String::from("Hello Rust World");
    let result1 = find_word(&text, "Rust");
    let result2 = find_word("Hello World", "World");

    let greeting = create_greeting("Alice");
    println!("{}", greeting);
}

요약

  • 일반적으로 &str을 사용하세요 - 더 유연하고 효율적입니다
  • String을 수정해야 할 때만 &mut String을 사용하세요
  • 소유권이 필요할 때만 String을 사용하세요

이러한 접근 방식은 Rust의 "최소 권한 원칙"을 따르며, API를 더 일반적이고 재사용 가능하게 만듭니다.

728x90
반응형