Rust 기본 : UTF-8 문자열 (Strings)
러스트는 기본 문자열 타입으로 UTF-8을 사용합니다.
UTF (Unicode Transformation Format)
&str, 문자열 슬라이스 (주소, 길이)
- &str은 문자열의 일부를 보거나 참조할 수 있지만, 내용을 변경할 수는 없습니다.
- &str은 UTF-8로 인코딩된 바이트의 연속을 참조하는 슬라이스입니다.
- 문자열 슬라이스는 실제 데이터를 소유하지 않고, 기존 데이터에 대한 참조만을 가집니다.
String (주소, 길이, 용량)
- String은 크기를 조정할 수 있으며, 내용을 수정하거나 추가할 수 있는 UTF-8로 인코딩된 문자열입니다.
- String 타입은 Rust의 표준 라이브러리에 포함되어 있으며, 메모리 관리와 관련된 여러 기능을 제공합니다.
use unicode_segmentation::UnicodeSegmentation;
fn main() {
println!("----- UNICODE ----------");
println!("crab: {}", '\u{1F980}'); // rust 🦀
let rust = "🦀";
let utf8_bytes = rust.as_bytes();
for byte in utf8_bytes {
print!("{:08b} ", byte);
}
println!();
println!("----- Create String ----------");
let s1 = "안녕 세계야! 🦀";
let s2 = String::from("안녕 세계야!");
let s3 = "안녕 세계야!".to_string();
let s4 = "안녕 세계야!".to_owned();
let s5 = &s4[..];
println!("{s5}");
println!("----- Manipulate String ----------");
let mut s = String::from("foo");
s.push_str(" bar");
println!("{s}");
s.replace_range(.., "baz");
println!("{s}");
println!("----- Concatenating String ----------");
// + operator
let s1 = String::from("Hello, ");
let s2 = String::from("World!");
// let s3 = s1 + &s2; // s1 소유권이 이동하기 때문에 다음 코드를 위해 주석처리.
// println!("{s3}");
let s4 = format!("{}-{}", s1, s2);
println!("{s4}");
let s1 = ["first", "second"].concat();
let s2 = format!("{}{}", "first", "second");
let s3 = concat!("first", "second");
let s4 = String::from("test");
let s5 = s4 + "okok"; // String type must be first
println!("----- Indexing String ----------");
let s1 = "🦀🦀🦀🦀🦀";
let s2 = &s1[0..4];
println!("{s2}");
print!("bytes: ");
for b in "नमस्ते".bytes() {
print!("{b} ");
}
println!();
// Scalar values are a basic unit in Unicode,
// and some user perceive characters are made up of multiple scaler values.
// chars() : Iterator over the unicode scaler values of the string.
print!("chars: ");
for c in "नमस्ते".chars() { // 유니코드 글자 단위 스칼라 값
print!("{c} ");
}
println!();
// In unicode, user perceived characters are known as grapheme clusters.
// cf) cargo add unicode-segmentation
// graphemes() : Iterator over the grapheme clusters
print!("graphemes: ");
for g in "नमस्ते".graphemes(true) { // 사용자 인식 문자 출력
print!("{g} ");
}
println!();
// Strings and function
let s1 = "Hello World!";
let s2 = String::from("Hello World!");
my_function(s1);
my_function(&s2); // deref coercion
// RUST UTF-8 코드의 문자열 찾기 성능이 linear 하다.
// Go 는 UCS4 Room 타입을 사용하여 문자열 찾기 성능을 constant 하게 향상한다.
}
// String 으로 리턴하는 이유는, 호출자가 스트링 ownership 획득을 위해서.
fn my_function(a: &str) -> String {
return format!("{}", a); // clone and ownership moved
}
UTF-8
1 character = 1 ~ 4 bytes
1,112,064 characters.
1 byte 문자 : ASCII
2 byte 문자 : 추가 라틴 문자, 히브리어, 아랍어
3 byte 문자 : 비 라틴 문자 세트, 한글, 가나, 간체
4 byte 문자 : 보조 다국어 평면 및 특수 목적 평면, 이모지, 역사적 스크립트 등.
🦀 이모지 UTF-8 코드 포인트(U+) 범위는 아래와 같다.
종류 | 범위 | 개수 | 설명 | |
Emoji Symbols | U+1F300 - U+1F5FF | 768 | 일반적인 이모지로 기호, 동물, 자연 현상, 음식, 스포츠 등을 포함 | |
Emoticons (Emotional Icons) | U+1F600 - U+1F64F | 80 | 얼굴 표현 중심의 감정을 나타내는 이모지 | |
Transport and Map Symbols | U+1F680 - U+1F6FF | 128 | 교통 수단과 지도 기호 관련 이모지 | |
Miscellaneous Symbols and Pictographs | U+1F900 - U+1F9FF | 256 | 다양한 기호, 유물, 판타지 캐릭터 등을 포함하는 추가적인 이모지 | |
Supplemental Symbols and Pictographs | U+1FA70 - U+1FAFF | 144 | 더 많은 활동, 새로운 동물, 기호 등을 포함하는 이모지 | |
Extended Pictographic | U+1F000 - U+1F02F | 48 | 주로 게임과 관련된 기호와 일부 전통 게임에서 사용되는 이모지 |
UTF-8 코드 변환
1 ~ 4 바이트 코드 포인트 변환 포멧
1 byte : 0xxxxxxx
2 byte : 110xxxxx 10xxxxxx
3 byte : 1110xxxx 10xxxxxx 10xxxxxx
4 byte : 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
위의 바이트 구성에서 x 부분만 따로 비트 취합하여 4 비트씩 끊어서 계산하면,
코드 포인트 U+ 범위는 아래와 같다.
1 byte = 0x00 ~ 0x7F
2 byte = 0x80 ~ 0x7FF
3 byte = 0x800 ~ 0xFFFF
4 byte = 0x10000 ~ 0x10FFFF
이제 예를 들어 문자 주소를 코드 포인트로 변환해보자.
Crab emoji : 4바이트 문자, 🦀
4 바이트 주소 구성 : 11110000 10011111 10100110 10000000
4 바이트 코드 포인트 변환 포멧 : 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
4 바이트 문자일 경우 변환 포멧의 x 부분의 주소 비트를 취합한다.
000 011111 100110 000000
이제 오른쪽 부터 4비트씩 끊어서 표기하면 코드 포인트가 된다.
0001 1111 1001 1000 0000
16진수로 변환
U+1F980
러스트 코드에서는 아래처럼 사용한다. \u{1F980}
println!("{}", '\u{1F980}'); 🦀
'개발 > 러스트 (Rust)' 카테고리의 다른 글
Rust 기본, 구조체 (Struct) Tuple structs (0) | 2024.08.06 |
---|---|
Rust 기본, 구조체 (Struct) Implementation blocks (0) | 2024.08.01 |
Rust 기본, 구조체 (Struct) (0) | 2024.07.24 |
Rust 기본, to_string() vs to_owned() (0) | 2024.07.20 |
Rust 기본, 슬라이스 (Slice) (0) | 2024.07.14 |
Rust 기본, 참조 (Borrow) (0) | 2024.07.09 |
Rust 기본, 소유권 (Ownership) (0) | 2024.07.06 |
Rust 기본, OBRM vs RAII (0) | 2024.07.06 |