반응형

간단하게 정리해본 Rust 강좌입니다. 



다음 문서를 기반으로 작성했습니다.



Tour of Rust

https://tourofrust.com/00_ko.html 



2022. 9. 12  최초작성




문자열

 

Rust에서 문자열은 유니코드입니다. 문자열의 데이터 타입은 &'static str입니다.

 

&는 메모리 내의 장소를 참조하고 있다는 의미이며, mut가 없다는 것은 컴파일러가 값의 변경을 허용하지 않는다는 뜻입니다

'static은 string 데이터가 프로그램이 끝날 때까지 유효하다는 것이고  str은  utf-8인 바이트 열을 가리키고 있다는 의미입니다

 

Rust 컴파일러는 문자열을  데이터 세그먼트에 저장합니다. 

 

fn main() {

    let a: &'static str = "hi 🦀";
   
    println!("{} {}", a, a.len());
}






utf-8

 

utf-8에선 하나의 문자가  1 ~ 4 사이의 바이트를 가집니다.  그로인해 사용 가능한 문자가 많아졌습니다.

 

한 가지 단점은 단순한 인덱싱(예: my_text[3]으로 네 번째 문자를 가져옴)으로는  문자를 찾을 수 없다는 점입니다. 바로 앞의 글자가 가변 길이를 가질 수 있어, 바이트 열에서 4번째 문자가 실제로 시작하는 위치가 달라질 수도 있습니다.

 

우리는 그 대신에 utf-8 바이트 열을 하나하나 돌면서 각각의 유니코드 문자가 실제로 어디에서 시작하는지 찾아야 합니다.




이스케이프 코드(escape code)

시각적으로 표현하기 어려운 문자를 이스케이프 코드로 대체하여 씁니다.

 

 

전체 목록은 아래 링크에 있습니다.

 

https://doc.rust-lang.org/reference/tokens.html



fn main() {

    let a: &'static str = "Ferris가 말하길:\t\"안녕하세요\"\n반가워요";

    println!("{}", a);
}






여러 줄로 된 문자열

 

Rust의 문자열은 기본적으로 여러 줄로 되어 있습니다.

줄바꿈 문자를 원하지 않을 경우, 줄 맨 뒤에 \를 사용하세요.



fn main() {


    // 줄바꿈이 적용되어 출력됩니다.
    let haiku: &'static str = "
        나는 쓰고, 지우고, 다시 쓴다
        다시 지우고, 그러고 나면
        양귀비 꽃이 핀다.
        - 가쓰시카 호쿠사이";

    println!("{}", haiku);


    // \를 사용함으로써 줄바꿈이 무시되고 한 줄로 출력됩니다.
    println!(
        "hello \
    world"
    ) // w 앞의 공백이 무시 되었음을 주의하세요
}






원시 문자열

 

원시 문자열은 r#"로 시작하고 "#로 끝나며 문자열을 있는 그대로 출력해줍니다. 

 

fn main() {

    let a: &'static str = r#"
        <div class="advice">
            원시 문자열은 일부 상황에서 유용합니다.
        </div>
        "#;
   
    println!("{}", a);

}

 




텍스트 파일에서 문자열 가져오기

 

include_str!를 사용하여 텍스트 파일을 읽어서 문자열로 가져올 수 있습니다. 

 

fn main() {

    let text = include_str!("main.rs");

    println!("{}", text);
}

 




문자열 슬라이스

 

문자열 슬라이스(slice) 는 인덱스를 지정하여 문자열의 일부를 가져오는 것입니다. utf-8에선 하나의 문자가 4바이트인 경우  문자의 일부를 가져올 수는 없습니다. 

문자열 슬라이스의 문자열 타입은 &str이며 여러가지 메서드를 제공합니다. 

 

슬라이스

 

슬라이스는 인덱스를 사용하여 문자열의 일부를 가져오는 것입니다. 

문자열 슬라이스를 위해 변수에 인덱스를 지정시 변수 이름 앞에 &를 붙여줘야 합니다. 

 

fn main() {

    let a = "hi 🦀";

    println!("문자열의 길이 {}", a.len()); // 문자열의 글자수가 아닌 바이트 길이입니다.

    let first_word = &a[0..2]; // 문자열의 인덱스는 0부터 시작, 0..2는 시작 인덱스 0부터이며 끝 인덱스 2를 포함하지 않음
    let second_word = &a[3..7]; // 3..7는 시작인덱스 3부터이며 끝 인덱스 7은 포함하지 않음, 러스트 그림문자는 4 바이트임

    println!("첫번째 단어 [{}] ,  두번째 단어 [{}]", first_word, second_word);
}





러스트  문자의 절반을 슬라이스 하려고하면  에러가 발생합니다.  러스트 문자의 절반만 가져오는 것은 허용되지 않기 때문입니다.

 

fn main() {

    let a = "hi 🦀";

    let half_crab = &a[3..5];

    println!("러스트 문자 반쪽 [{}]", half_crab);
}






find

 

find 메서드는 지정한 문자열이 발견된 인덱스를 Option<usize>로 리턴합니다. 

 

fn main() {

    let a = "12345678901234567890";

    println!("{:?}", a.find("789")); // 문자열 "789"가 처음 발견된 인덱스를 Option<usize>로 리턴합니다.

    println!("{:?}", a.find("111")); // 문자열 "111"을 발견할 수 없어서 None를 리턴합니다.

}






is_empty

 

is_empty 메서드는 문자열의 길이가 0인 경우 ture를 리턴합니다. 



fn main() {

    let a = "";

    println!("{:?}", a.is_empty());
}





starts_with / ends_with

 

starts_with 메서드는 문자열의 앞에 지정한 문자열이 포함되어 있으면 true를 리턴합니다.

ends_with 메서드는 문자열의 끝에 지정한 문자열이 포함되어 있으면  true를 리턴합니다.

 

fn main() {

    let a = "abcdefg";

    println!("{:?}", a.starts_with("abc")); // 문자열의 앞에 "abc"가 포함되어 있으면 ture를 리턴합니다.
    println!("{:?}", a.ends_with("fg")); // 문자열의 끝에 "fg"가 포함되어 있으면 ture를 리턴합니다.
}






문자

 

유니코드를 다루는 것이 어렵다보니, Rust에서는 utf-8 바이트 열을 char 자료형의 vector로 돌려주는 기능을 제공합니다.



use std::mem;


fn main() {

    let text = "hi 🦀~";

    // 문자열에서 문자들을 char의 vector로 가져옵니다
    let chars = text.chars().collect::<Vec<char>>();

    println!("{:?}", chars); // 문자별로 분리된 것을 볼 수 있습니다.
    println!("{}", chars.len()); // 벡터에 저장된 문자의 개수는 5개입니다.

    // 각 문자의 크기가 4바이트인 것을 볼 수 있습니다.
    println!("{} {} {} {} {}", mem::size_of_val(&chars[0]), mem::size_of_val(&chars[1]), mem::size_of_val(&chars[2]), mem::size_of_val(&chars[3]), mem::size_of_val(&chars[4]));

    // 문자열에서 슬라이스로 가져온 문자 하나의 크기는 1바이트입니다.
    println!("{} {}", &text[0..1], mem::size_of_val(&text[0..1]));

}






스트링

 

String은 utf-8 바이트 열을 heap memory에 소유하는 struct입니다.

String의 메모리는 heap에 있기 때문에, 문자열과는 달리 늘리거나 변경하는 등을 할 수 있습니다.



fn main() {

    let mut text = String::from("hello");
    println!("{}", text);
   
    // 문자열을 결합합니다.
    text.push_str(" world");
    println!("{}", text);

    // 문자열을 결합합니다.
    text = text + "!";
    println!("{}", text);

    //부분 문자열을 교체합니다.
    text = text.replace("world", "universe");
    println!("{}", text);

    // 대문자로 변환합니다.
    text = text.to_uppercase();
    println!("{}", text);

    // 소문자로 변환합니다.
    text = text.to_lowercase();
    println!("{}", text);

    // 문자열의 공백을 제거합니다.
    let mut text = String::from(" momo   ");
    println!("{}", text);
    text = text.trim().to_string();
    println!("{}", text);
}

 




함수의 매개변수로서의 텍스트

 

문자열과 string은 일반적으로 함수에 문자열 슬라이스 형태로 전달됩니다. 이 방법은 소유권을 넘길 필요가 없어 대부분의 경우에 유연성을 제공합니다.



fn say_it_loud(msg: &str) {
    println!("{}!!!", msg);
}

fn main() {

    // 문자열 &'static str을 &str로 넘겨줄 수 있습니다.
    let s : &'static str = "hello";
    say_it_loud(s);
   
    // 문자열 String을 &str로 넘겨줄 수  있습니다.
    let s = String::from("goodbye");
    say_it_loud(&s);
}

 




문자열 합치기

 

문자열을 합치기 위해 concat과 join을 사용할 수 있습니다. 



fn main() {

    let helloworld = ["hello", " ", "world", "!"].concat();

    //문자열을 결합시 사이에 넣을 문자로 콤마를 지정합니다.
    let abc = ["a", "b", "c"].join(",");

    println!("{}", helloworld);
    println!("{}",abc);

}

 




문자열 양식 만들기

 

format! 매크로를 사용하면 문자열을 삽입할 위치를 지정할 수 있습니다. 

 

fn main() {
    let a = 42;
    let f = format!("삶, 우주, 그리고 모든 것에 대한 해답: {}", a);
   
    println!("{}", f);
}






문자열 변환

 

대부분의 데이터 타입에 to_string을 사용하면 문자열로 변환이 가능합니다. 



fn main() {
   
    let a = 42;

    let a_string = a.to_string();
   
    println!("{}", a);
}

 


반응형

진행해본 결과물을 기록 및 공유하는 공간입니다.
잘못된 부분이나 개선점을 알려주시면 반영하겠습니다.


소스코드 복사시 하단에 있는 앵커 광고의 왼쪽 위를 클릭하여 닫은 후 해야 합니다.


문제가 생기면 포스트와 바뀐 환경이 있나 먼저 확인해보세요.
질문을 남겨주면 가능한 빨리 답변드립니다.


제가 쓴 책도 한번 검토해보세요 ^^

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기

댓글을 달아 주세요

TistoryWhaleSkin3.4">