[Rust] 문자열: str 타입
처음에 Rust를 공부하기 시작하면 가장 이해하기 어려운 것 중 하나가 아마 str일 것이다.
str은 쉽게 말하면 문자열의 읽기용 참조를 나타내기 위한 참조 전용 타입이다. 길이를 알 수 없는 1바이트의 슬라이스 타입이라서 참조 없이 사용하는게 불가능하다. 그리고 당연히 UTF-8로만 표현된다.
str은 단순히 참조를 나타내는 것일 뿐이고, 실제로 데이터가 적재되는 장소는 컨텍스트에 따라 다르다.
&str은 원본 데이터에 상관없이 불변 문자열임을 공통적인 형태로 사용하기 위한 추상화 수단일 뿐이다.
위치 1: 문자열 리터럴
큰따옴표로 감싸는 문자열 리터럴들은 &'static str 타입으로 표현된다. 프로그램이 종료되는 동안 영원히 존재하는 정적 참조라는 뜻이다.
C/C++ 같은 저수준 언어에 대한 경험이 있다면 어느정도 알텐데, 이 문자열 데이터 상수 자체는 정적으로 바이너리에 임베딩된다. 정확히는 데이터 세그먼트, rodata 세그먼트에 배치된다.
그리고 그 주소를 참조해서 사용하는 것이다.
별다른 가공 없이 이런 문자열을 다른 상수나 변수에 넘기더라도 그 참조만을 공유할 것이다.
위치 2: 힙 데이터 (String)
그냥 문자열 리터럴로 고정 할당을 한게 아니라면, 이외에는 보통 그냥 힙에 올라간 문자열 시퀀스를 참조한다.
가장 대표적인 예시는 String에 대한 참조다.
String은 사실 단순한 바이트 단위의 벡터다.
문자열을 I/O로 받거나, 수정하거나, 가공할 때가 있을때는 항상 String을 통해 힙에 올라간 채로 사용된다고 보면 된다.
String은 근본적으로 그냥 벡터 데이터다보니, 함수로 넘기거나 할때마다 항상 그대로 복사하는 것은 비효율적이다. 그래서 단순 readonly 데이터로 넘길때는 &str으로 변환해서 넘기는 것이 일반적인 사용법이다.
위치 3: 스택 바이트 배열
굉장히 드문 사용례지만, 그냥 스택에 위치한 바이트 배열을 가리킬 수도 있다.
이런 경우다.
이러면 스택에 위치한 저 bytes를 가리키기만 한다.
근데 저렇게 쓸일이 있나 모르겠다. 나는 본 적 없다.
참조
https://doc.rust-lang.org/std/primitive.str.html
https://stackoverflow.com/questions/24158114/what-are-the-differences-between-rusts-string-and-str
https://stackoverflow.com/questions/77591134/are-rust-string-literal-values-stored-on-the-heap