Page

관련 포스팅

2023년 9월 16일 토요일

Week02 - Rust 문법 (String 및 출력)

이번에는 string에 대해서 정리해본다.

pub fn run() {
    let s1 = "hello"; // type &str
    println!("{}", s1.len());

    let s2 = "世界";
    println!("{}", s2.len()); // length is # of bytes
    println!("{}", s2.chars().count());

    for x in s2.chars() {
        println!("{x}");
    }

    for x in s2.bytes() {
        println!("{x}");
    }

    let s3 = "नमस्ते";
    println!("{s3}");
    for x in s3.chars() {
        println!("{x}");
    }

    // print_string(&s1);
    print_str(&s1);

    let t = "hello".to_string();
    // let t = String::from("hello");
    // let t = "hello".to_owned();
    print_string(&t);
    print_str(&t);
}

// only works for &String
fn print_string(s: &String) {
    for x in s.chars() {
        println!("{x}");
    }
}

// better version: works for both &str and &String
fn print_str(s: &str) {
    for x in s.chars() {
        println!("{x}");
    }
}

run 함수는 여러 가지 문자열 처리 예제를 보여주고 있다. 이 함수는 다양한 타입의 문자열(&str, String)과 문자열 관련 메서드(len, chars, bytes)를 사용하고 있다.

주요 포인트

  • s1s2&str 타입의 문자열이다. s1.len()s2.len()은 문자열의 바이트 길이를 출력한다.
  • s2.chars().count()s2의 문자 개수를 반환한다.
  • for x in s2.chars()s2의 각 문자를 순회하면서 출력한다.
  • for x in s2.bytes()s2의 각 바이트를 순회하면서 출력한다.
  • s3는 다른 언어의 문자를 포함하고 있다. 이것도 chars() 메서드로 순회가 가능하다.
  • print_string 함수는 &String 타입만 받을 수 있다.
  • print_str 함수는 &str&String 둘 다 받을 수 있다. 이게 더 유연하다.

함수 분석

  1. print_string: &String 타입을 인자로 받아서, 문자열의 각 문자를 출력한다.
  • 네, 맞다. &String을 사용하는 이유는 함수 내에서 s의 소유권을 가져가지 않고, 대신 빌려(read-only) 사용하기 위해서다. 이렇게 하면 함수가 끝난 후에도 원래의 String이 그대로 유지된다.
  • print_string 함수는 문자열을 출력만 하고 수정하지 않으니, 소유권을 가져갈 필요가 없다. 그래서 &String 형태로 borrow해서 사용하는 것이 좋다. 이 방식은 메모리 효율성을 높이고, 함수 사용을 더 유연하게 만든다. 다른 코드에서 해당 String을 계속 사용할 수 있게 해주기 때문이다.
  1. print_str: &str 타입을 인자로 받아서, 문자열의 각 문자를 출력한다. &str&String 둘 다 이 함수에 전달할 수 있다.

코드의 특징

  • let t = "hello".to_string();와 같은 방식으로 &str에서 String으로 변환할 수 있다. 이것은 print_string(&t); 같은 함수에서 사용할 수 있게 한다.
    • "hello".to_string()은 "hello"라는 문자열을 String 타입으로 바꿔준다. 원래 "hello"&str 타입이다.
    • String&str 둘 다 문자열을 나타내지만, 다르게 사용되는 경우가 있다. 예를 들어, print_string(&t); 함수는 &String 타입을 필요로 한다. 그래서 "hello" 같은 &str 타입을 String 타입으로 바꿔줘야 print_string(&t); 함수에 넣을 수 있다.
    • 간단하게 말하면, "hello".to_string()은 "hello"라는 문자열을 print_string(&t); 같은 함수에서 쓸 수 있도록 타입을 바꿔주는 것이다.
  • 문자열의 길이(len)는 바이트 단위이다. 이것은 ASCII 문자와 다국어 문자에서 차이가 난다.
  • chars()bytes()는 문자열을 다른 단위로 순회하는 데 사용된다.

이 코드는 Rust에서 문자열을 다루는 다양한 방법과 메서드를 잘 보여주고 있다.

String과 &str의 차이

String&str 두 타입 모두 Rust에서 문자열을 다루기 위해 사용되지만, 중요한 차이점이 몇 가지 있다.

  1. 소유권:

    • String은 소유권을 가지는 타입이다. 즉, String 변수가 사라지면 그 안에 저장된 문자열 데이터도 메모리에서 사라진다.
    • &str은 대체로 빌려온 문자열에 대한 참조다. 원래 문자열이 어딘가에 저장되어 있고, &str은 그 위치를 가리키는 것이다.
  2. 변경 가능성:

    • String은 변경이 가능하다. 즉, 문자를 추가하거나 삭제할 수 있다.
    • &str은 기본적으로 변경이 불가능하다.
  3. 메모리:

    • String은 동적 메모리를 사용해서 필요한 만큼 크기가 늘어난다.
    • &str은 정해진 크기와 위치에 문자열을 저장한다.

예를 들어,

  • String: "hello".to_string() 또는 String::from("hello")을 통해 만들 수 있다.
  • &str: 리터럴 방식으로 "hello"처럼 만들 수 있다.

간단하게 말하면, String은 변경 가능하고 소유권을 가지는 문자열이고, &str은 빌려온 또는 변경 불가능한 문자열인 것이다.

댓글 없음:

댓글 쓰기

관련 포스팅