인프런 커뮤니티 질문&답변

열심히하자님의 프로필 이미지
열심히하자

작성한 질문수

우아한 고성능 프로그래밍 언어 Rust 입문 및 활용

문자열 리터럴이 너무 어려워요ㅠㅠ

해결된 질문

작성

·

444

1

문자열 리터럴이 뭘 뜻하는지 잘 모르겠어요.

리터럴이 말 그대로 데이터 값 그 자체라고 생각했는데요 (ex 2, 4, "hello")

 

그런데 강의 중 "문자열 리터럴이 특정 영역에 있는 문자열 데이터를 참조하고 있는 값"이라고 설명하셔서 혼란스러워요.

그럼 문자열 리터럴은 결국 문자열을 가리키고 있는 포인터인가요?

let hello: &str = "hello"

 

그리고 "문자열 리터럴이 특정 영역에 있는 문자열 데이터를 참조하고 있는 값" -> 여기서 특정 영역은 data 영역을 말하는 것일까요?

IMG_0894.jpg

리터럴이라는 용어 자체가 그냥 데이터 값이라고 알고 있었는데, 리터럴이 참조 값이었고 타입은 문자열 슬라이스 타입이어서 헷갈려요ㅠㅠ 도와주세요

 

 

 

답변 1

3

김대현님의 프로필 이미지
김대현
지식공유자

오우, 예리한 질문 감사합니다. 제 설명이 부족하고 혼란을 끼친 것 같습니다.

 

"리터럴"은 알고계시는 대로, 어떤 값을 "소스코드상에 기재해서 작성한 값"이 맞습니다. true, false, 1234, 0.12, "hello" 등등등 어떤 구체적인 값을 소스코드에 작성한 데이터입니다.

 

그리고 이 값들은 소스코드가 컴파일된 프로그램 결과물 어딘가에 데이터의 형태로 들어있게 됩니다. 그리고 그 프로그램이 실행되는 런타임에는 메모리 어딘가에 적재되고, 실행중에 "참조"해서 사용하게 될 것입니다.

 

프로세스가 실행되는 메모리 영역은 크게 "스택"과 "힙"이 있고요, 이 둘은 실행 중에 할당과 해제를 반복해가며 운용될 것입니다. 하지만, 프로그램에 데이터로 하드코딩된 데이터의 경우, 고정된 영역에 프로세스가 종료될 때까지 유지되겠지요. 이 영역을 데이터 영역이라고도 부르고, 코드 영역이라고도 부르는 것 같습니다.

 

그래서,

let hello: &str = "hello";

이 문장에서, "hello"가 리터럴이 되고요, hello라는 변수는 그 리터럴을 참조하고 있는 슬라이스가 됩니다. (레퍼런스는 &String타입이 되고, 이걸 더 범용적으로 "범위를 지정해서 참조해 쓰는 타입"이 &str로 슬라이스 타입입니다. 문자열 리터럴은 &str로 슬라이스 타입을 써서 사용합니다.)

 

결국 그림으로 그려주신 내용이 정확합니다. 리터럴 값 자체는 프로세스가 실행되면 메모리 영역 중 특정(데이터 또는 코드라고 부르는) 영역에 위치하게 될 테고, 그걸 참조한 슬라이스 변수를 통해서 쓰게 되는 것이므로, '문자열 리터럴이 특정 영역에 있는 문자열 데이터를 참조하고 있는 값'이라는 표현보다는, '문자열 리터럴 "hello"를 슬라이스 형태로 참조해 사용하는 변수 hello'라는 표현이 더 적확할 것 같습니다.

 

애써 제 입장에서 변명을 해보자면, 리터럴 값을 결국 접근해서 사용할 수 있는 방법은 슬라이스를 통한 접근 밖에 없기 때문에, 문자열 리터럴은 "사실상"(effectively) 문자열 슬라이스다라고 주장한 거라고 우겨볼 수도 있겠습니다. (궁색한 변명 죄송합니다)

 

제가 부족해서 혼란을 끼쳤습니다. 부족한 설명에도 열심히 학습해주셔서 감사합니다. 또 질문 있으시면 언제든 편하게 말씀해주세요! 정확한 표현을 위해 노력하겠습니다.

덕분에 저도 정리가 됐어요! 감사합니다 👍

문자열 슬라이스가 낯설어서 더 헷갈렸던 것 같아요.

(문자열 슬라이스로 리터럴을 참조하다니)

지금은 enum 듣고 있어요ㅋㅋ 완강을 향해 다시 달려가겠습니다

Rust는 문자열을 u8 로 저장합니다.

fn main () {
    let byte_escape = "I'm writing \x52\x75\x73\x74!";
    println!("What are you doing\x3F (\\x3F means ?){}", byte_escape);
}

해보시면 재밌는 결과가 나옵니다. ㅎㅎ

 

fn main () {
    let byte_escape = "안녕하세요";
    println!("{:?}", byte_escape.as_bytes());
}

 

result

[236, 149, 136, 235, 133, 149, 237, 149, 152, 236, 132, 184, 236, 154, 148]

 

Strings

There are two types of strings in Rust: String and &str.

A String is stored as a vector of bytes (Vec<u8>), but guaranteed to always be a valid UTF-8 sequence. String is heap allocated, growable and not null terminated.

&str is a slice (&[u8]) that always points to a valid UTF-8 sequence, and can be used to view into a String, just like &[T] is a view into Vec<T>.

https://rustwiki.org/en/rust-by-example/std/str.html

image

우와 문자열에 16진수를 바로 적을 수 있네요

 

byte_escape.as_bytes()

ㄴ 이상해요;;; u8 리스트로 되어 있지만 출력할 때는 문자열로 출력을 하는군요

열심히하자님의 프로필 이미지
열심히하자

작성한 질문수

질문하기