문자열utf-8이란 무엇인가예외처리문자여러 줄로 된 문자열원시 문자열파일에서 문자열 가져오기문자열 슬라이스문자String함수의 매개변수로서의 텍스트스트링 만들기스트링 양식 만들기스트링 변환The Rust Programming Language 링크
문자열
- 문자열은 언제나 유니코드
- 문자열의 자료형은
&'static str
&
는 메모리 내의 장소를 참조하겠다는 것- →
&mut
가 빠졌다는 것은 컴파일러가 값의 변경을 허용하지 않을 것임 'static
은 string 데이터가 프로그램이 끝날 때까지 유효하다는 의미- Never DROP
str
은 언제나 유효한 utf-8인 바이트 열
fn main() { let a: &'static str = "hi 🦀"; println!("{} {}", a, a.len()); }
메모리 상세
문자열을 프로그램 메모리의 데이터 세그먼트에 저장함
utf-8이란 무엇인가
- utf-8은 1에서 4 바이트의 가변 길이 바이트로 사용 가능한 문자의 범위를 늘림
- 가변 길이 바이트 = 불필요한 바이트 X
- 단점
- 단순한 인덱싱 (ex>
my_text[3]
)으로 문자를 찾을 수 없음 - 문자마다 바이트 크기가 다르기 때문
- utf-8 바이트 열을 하나하나 돌면서 유니코드 문자가 어디부터 시작하는지 찾아야 함
- O(1) → O(n)
- 🐠🐙🐟🐬🐋
예외처리문자
\n
- 줄바꿈
\r
- 캐리지리턴
\t
- 탭
\\
- 역슬래시
\0
- null
\'
- 작은 따옴표
fn main() { let a: &'static str = "Ferris가 말하길:\t\"안녕하세요\""; 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!
매크로를 사용하여 로컬 파일에서 텍스트 로드
let 00_html = include_str!("00_ko.html");
문자열 슬라이스
- 문자열 슬라이스는 메모리 상의 바이트 열에 대한 참조
- 언제나 유효한 utf-8 바이트가 되어야 함
&str
의 흔히 사용되는 메소드len
은 문자열의 바이트 길이를 가져옴starts_with
/ends_with
는 기본적인 비교에 사용is_empty
는 길이가 0일 경우 truefind
는 주어진 텍스트가 처음 등장 위치인Option<usize>
값을 리턴
fn main() { let a = "hi 🦀"; println!("{}", a.len()); let first_word = &a[0..2]; let second_word = &a[3..7]; let char_idx = match a.find("🦀") { None => -1, Some(v) => v as i32, }; println!("{}", char_idx); // let half_crab = &a[3..5]; 실패 // Rust는 유효하지 않은 유니코드 문자열의 slice를 허용하지 않습니다 println!("{} {}", first_word, second_word); }
문자
- utf-8 바이트 열을
char
자료형의 벡터로 돌려주는 기능을 제공
char
자료형은 하나의 크기가 4 bytes
fn main() { // 문자열을 char의 vector로 가져옵니다 let chars = "hi 🦀".chars().collect::<Vec<char>>(); let bytes_len = chars.len() * std::mem::size_of::<char>(); println!("{}", chars.len()); // 4여야 합니다 println!("{}", bytes_len); // 16 // char가 4 바이트이므로 u32로 변환할 수 있습니다 println!("{}", chars[3] as u32); // 하나씩 문자 및 바이트 값 출력 for ch in chars { println!("{}\t| 0x{:0>8x}", ch, ch as u32); } }
String
- String은 heap memory에 저장된 utf-8 바이트 열을 소유하는 struct
- → heap에 있기 때문에, 문자열과는 달리 늘리거나 변경 가능
- 자주 쓰는 메소드
push_str
string의 맨 뒤에 utf-8 바이트 추가replace
utf-8 바이트 열을 다른 것으로 교체to_lowercase
/to_uppercase
대소문자 변경trim
공백 제거
- String이 drop 되면, 그 heap memory도 함께 drop
&str
값으로 확장후 자신을 리턴하는+
연산자 제공
fn main() { let mut helloworld = String::from("hello"); helloworld.push_str(" world"); helloworld = helloworld + "!"; println!("{}", helloworld); }
함수의 매개변수로서의 텍스트
- 문자열(
&'static str
)과 String은 일반적으로 함수에 문자열 슬라이스 형태로 전달
- → 소유권을 넘길 필요가 없어 대부분의 경우에 유연성 제공
fn say_it_loud(msg: &str) { println!("{}!!!", msg.to_string().to_uppercase()); } fn main() { // say_it_loud는 &'static str을 &str로 대여할 수 있습니다 say_it_loud("hello"); // say_it_loud는 또한 String을 &str로 대여할 수 있습니다 say_it_loud(&String::from("goodbye")); }
스트링 만들기
concat
과join
으로 String 만들기
fn main() { let helloworld = ["hello", " ", "world", "!"].concat(); let abc = ["a", "b", "c"].join(","); println!("{}", helloworld); println!("{}", abc); }
스트링 양식 만들기
format!
매크로 문자열 내{}
를 파라메터로 하여 String 생성
format!
은println!
과 동일한 매개변수화 된 string을 사용
fn main() { let a = 42; let f = format!("삶, 우주, 그리고 모든 것에 대한 해답: {}", a); println!("{}", f); }
스트링 변환
to_string
을 이용하여 String으로 변환
parse
로 string이나 문자열을 다른 자료형으로 변환 →Result
리턴
fn main() -> Result<(), std::num::ParseIntError> { let a = 42; let a_string = a.to_string(); let b = a_string.parse::<i32>()?; println!("{} {}", a, b); Ok(()) }
Float32 자료형 형변환 예제
fn main() -> Result<(), std::num::ParseFloatError> { // <- Error 타입 주의! let pi = 3.14159; let pi_string = pi.to_string(); let pi2 = pi_string.parse::<f32>()?; // <f32> 부동 소수점 타입으로 지정 println!("{} {}", pi, pi2); Ok(()) }
The Rust Programming Language 링크
- 4.3 슬라이스