blog

| 기본 데이터 유형 | 부울, 문자, 튜플, 포인터 유형

Rust의 부울 유형인 bool에는 이 유형에 공통적인 참과 거짓의 두 값이 있습니다. == 및 <와 같은 비교 연산자는 2 < 5의 경우 참과 같은 부울 결과를 생성합니다....

Oct 9, 2025 · 11 min. read
シェア

폭풍 같은 로리타 - 징크스

부울 유형

Rust의 부울 유형에는 이 유형에 공통적인 참과 거짓의 두 가지 값이 있으며 ==, < 등과 같은 비교 연산자는 2 < 5에 대해 참과 같은 부울 결과를 생성합니다.

주로 짧은 스케치로 구성된 문학의 한 유형입니다.

Rust의 부울 타입은 자바스크립트의 부울 타입과 유사하지만, Rust는 강력한 타입이므로 암시적 타입 변환의 오버헤드를 줄이고 성능을 개선하기 위해 ===를 사용할 필요가 없습니다.

많은 언어가 부울 값이 필요한 컨텍스트에서 다른 유형의 값을 사용하는 것에 대해 느슨합니다. 예를 들어 C와 C++는 문자, 정수, 부동 소수점 및 포인터를 부울 값으로 암시적으로 변환하여 if 또는 while 문에서 조건으로 직접 사용할 수 있도록 하고, Python은 문자열, 리스트, 사전 및 심지어 집합을 부울 컨텍스트에서 허용하고 값이 null이 아닌 경우 참으로 취급합니다. 그러나 Rust는 매우 엄격합니다. if 및 while과 같은 제어 구조는 단락 논리 연산자 && 및 와 마찬가지로 조건이 부울 표현식이어야 합니다. 만약 x! = 0 { ... }가 아니라 if x { ... }.

Rust의 연산자는 부울 값을 정수로 변환합니다:

assert_eq!(false as i32, 0);
assert_eq!(true as i32, 1);

그러나 as는 다른 방향으로 변환할 수 없습니다. 대신 x! = 0.

부울은 단일 비트로만 표현하면 되지만, Rust는 메모리에서 정수 바이트를 사용하여 부울 값을 표현하므로 이에 대한 포인터를 생성할 수 있습니다.

문자

Rust의 문자 유형 char는 단일 유니코드 문자를 비트 값으로 나타냅니다.

Rust는 개별 문자에는 문자 유형을 사용하지만 문자열과 텍스트 스트림에는 UTF-8 인코딩을 사용합니다. 따라서 문자열은 문자 배열이 아닌 UTF-8 바이트 시퀀스로 텍스트를 표현합니다.

문자 리터럴은 작은따옴표로 묶인 문자(예: '8' 또는 '! . 전폭 유니코드 문자도 사용할 수 있습니다. '錆'는 일본어 한자로 사비를 나타내는 문자 리터럴입니다.

바이트 리터럴과 마찬가지로 표 3-10에 표시된 것처럼 일부 문자는 백슬래시로 이스케이프해야 합니다.

표 3-10: 백슬래시로 이스케이프할 문자

작은따옴표''\''
백슬래시'\\\'
줄 바꿈' '
Enter' '
스케줄링'\t'

원하는 경우 문자의 유니코드 코드 포인트를 16진수로 작성할 수도 있습니다.

  • 코드 포인트가 U+0000 ~ U+007F 범위에 있는 경우 문자는 '\xHH'로 작성할 수 있으며, 여기서 HH는 16진수 두 자리입니다. 예를 들어 문자 리터럴 '*'와 '\x2A'는 문자 *의 코드 포인트가 16진수에서 42 또는 2A이므로 동일합니다.
  • 모든 유니코드 문자는 '\u{HHHHHH}' 형식으로 작성할 수 있으며, 여기서 HHHHH는 최대 6자리 16진수이며 평소처럼 밑줄로 그룹화할 수 있습니다. 예를 들어 문자 리터럴 '\u{CA0}'는 유니코드에서 반대를 나타내는 데 사용되는 칸나다 문자 'ಠ_ಠ'인 문자 'ಠ'를 나타냅니다. 동일한 리터럴은 'ಠ'로 축약할 수 있습니다.

주로 짧은 스케치로 구성된 문학의 한 유형입니다.

char는 항상 0x0000에서 0xD7FF 또는 0xE000에서 0x10FFFF 범위의 유니코드 코드 포인트를 포함합니다. char는 "하프 서로게이트"의 코드 포인트나 유니코드 코드 포인트 공간을 벗어난 값은 절대 아닙니다. rust는 타입 시스템과 동적 검사를 사용하여 다음을 보장합니다. Rust는 타입 시스템과 동적 검사를 사용하여 문자 값이 항상 허용된 범위 내에 있는지 확인합니다.

Rust는 문자형과 다른 유형을 암시적으로 변환하지 않습니다. as 변환 연산자를 사용하여 문자를 정수로 변환할 수 있으며, 1비트 미만인 유형의 경우 문자 값의 상위 비트가 잘립니다:

assert_eq!('*' as i32, 42);
assert_eq!('ಠ'를 u16으로, 0xca0);
assert_eq!('ಠ'를 i8로, -0x60); // U+0CA08비트로 잘리고 서명됨

반대로 생각하면, Rust는 의도적으로 as 연산자가 매우 낮은 오버헤드와 안정적인 변환만 수행하도록 하기 때문에 u8은 as 연산자로 char로 변환할 수 있는 유일한 유형이지만, u8 이외의 모든 정수는 유니코드 코드 포인트 이외의 값을 포함할 수 있으므로 이러한 변환은 런타임 검사의 대상이 됩니다. 대안으로, 표준 라이브러리 함수 std::char::from_u32는 임의의 u32 값을 받아 Option<char>을 반환합니다: u32가 허용된 유니코드 코드 포인트가 아닌 경우 from_u32는 None을 반환하고 그렇지 않으면 Some(c)를 반환하며, 여기서 c는 a로 변환한 결과입니다. char로 변환한 결과입니다.

표준 라이브러리는 문자에 대한 몇 가지 유용한 메서드를 제공하며, 온라인 문서에서 "char" 및 "std::char" 모듈 아래에서 찾을 수 있습니다.

assert_eq!('*'.is_alphabetic(), false);
assert_eq!('β'.is_alphabetic(), true);
assert_eq!('8'.to_digit(10), Some(8));
assert_eq!('ಠ'.len_utf8(), 3);
assert_eq!(std::char::from_digit(2, 10), Some('2'));

고립된 문자는 문자열과 텍스트 스트림보다 당연히 덜 유용하며, 섹션 3.7에서는 Rust의 표준 문자열 유형과 텍스트 처리에 대해 설명합니다.

튜플

튜플은 값 쌍 또는 트리플, 쿼드러플, 퀸터플 등 다양한 유형의 값으로 이루어진 집합입니다. 튜플은 쉼표로 구분하고 한 쌍의 괄호로 묶은 요소의 시퀀스로 작성할 수 있습니다. 예를 들어, 첫 번째 요소가 정적으로 할당된 문자열이고 두 번째 요소가 유형 이 정수인 튜플을 예로 들 수 있습니다. 튜플 값 t가 주어지면 t.0, t.1 등을 통해 해당 요소에 액세스할 수 있습니다.

튜플은 두 유형 모두 값의 정렬된 시퀀스를 나타낸다는 점에서 배열과 다소 유사합니다. 많은 프로그래밍 언어에서 이 두 개념을 혼합하거나 결합하지만 Rust에서는 상당히 다릅니다. 한편으로 튜플의 각 요소는 다른 유형을 가질 수 있는 반면 배열의 요소는 모두 같은 유형이어야 합니다. 반면에 튜플은 t.4와 같은 상수로만 인덱싱할 수 있습니다. ith 요소를 t.i 또는 t[i]로 작성하여 얻을 수 없습니다.

Rust 코드는 종종 튜플 타입을 사용하여 함수에서 여러 값을 반환합니다. 예를 들어, 다음 선언에 표시된 것처럼 문자열 슬라이스의 split_at 메서드는 문자열을 반으로 분할하여 반환합니다:

fn split_at(&self, mid: usize) -> (&str, &str);

반환 유형 두 문자열 조각의 튜플입니다. 반환 값의 각 요소는 패턴 일치 구문을 사용하여 다른 변수에 할당할 수 있습니다:

let text = "I see the eigenvalue in thine eye";
let (head, tail) = text.split_at(21);
assert_eq!(head, "I see the eigenvalue ");
assert_eq!(tail, "in thine eye");

이는 서면으로 작성하는 것보다 가독성이 높습니다:

let text = "I see the eigenvalue in thine eye";
let temp = text.split_at(21);
let head = temp.0;
let tail = temp.1;
assert_eq!(head, "I see the eigenvalue ");
assert_eq!(tail, "in thine eye");

또한 튜플이 초소형 구조체 유형으로 사용되는 것을 볼 수 있습니다. 예를 들어 2장의 만델브로트 프로그램에서는 이미지를 그려서 디스크에 쓰는 함수에 이미지의 너비와 높이를 전달해야 합니다. 이를 위해 너비 멤버와 높이 멤버를 가진 구조체를 선언할 수도 있지만, 이렇게 명백한 용도로 작성하기에는 다소 번거롭기 때문에 튜플만 사용합니다:

///  `pixels`버퍼 쓰기는`filename`문서에서
fn write_image(filename: &str, pixels: &[u8], bounds: (usize, usize))
 -> Result<(), std::io::Error>
{ ... }

바운드 매개변수는 두 개의 usize 값의 튜플인 , 유형입니다. 물론 별도의 너비 및 높이 매개변수로 작성할 수도 있으며 최종 머신 코드는 본질적으로 동일합니다. 하지만 요점은 명확하게 생각해야 한다는 것입니다. 크기는 두 개의 값이 아니라 하나의 값으로 생각해야 하며 튜플을 사용하면 이러한 의도를 더 정확하게 파악할 수 있습니다.

일반적으로 사용되는 또 다른 튜플 유형은 제로 튜플입니다. Rust는 의미 있는 값을 전달할 수 없지만 컨텍스트에서 여전히 일부 유형을 전달해야 하는 경우 단위 유형을 사용합니다.

예를 들어 값을 반환하지 않는 함수는 반환 유형이 ()입니다. 표준 라이브러리의 std::mem::swap 함수는 의미 있는 반환값이 없으며 단순히 두 인자의 값을 교환할 뿐입니다. std::mem::swap은 다음과 같이 선언됩니다:

fn swap<T>(x: &mut T, y: &mut T);

이 <T>는 스왑이 일반적이라는 것을 의미합니다. T 타입의 모든 값에 대한 참조를 전달할 수 있습니다. 그러나 이 서명에서는 스왑의 반환 유형이 모두 생략되어 있으며, 아래 전체 내용을 축약하여 설명합니다:

fn swap<T>(x: &mut T, y: &mut T) -> ();

마찬가지로 앞서 언급한 write_image 예제의 반환 유형은 Result<(), std::io::Error>, 이는 함수가 실패 시에는 std::io::Error 값을 반환하지만 성공 시에는 아무것도 반환하지 않음을 의미합니다.

원하는 경우 튜플의 마지막 요소 뒤에 쉼표를 붙일 수 있습니다(유형과 같음, 표현식과 같음).Rust에서는 항상 사용할 수 있는 곳에 쉼표를 추가할 수 있습니다. 일반 독자에게는 이상하게 보일 수 있지만 여러 줄 목록의 끝에 항목을 추가하거나 제거하면 차이점을 표시할 때 더 쉽게 읽을 수 있습니다.

일관성을 위해 단일 값을 포함하는 튜플도 있습니다. 리터럴은 단일 문자열을 포함하는 튜플입니다. 여기서 값 뒤의 쉼표는 단일 값 튜플을 단순한 괄호 표현식과 구분하기 위해 필요합니다.

주로 짧은 스케치로 구성된 문학의 한 유형입니다.

자바스크립트에는 튜플의 개념이 없으며, 배열에 약간의 JS와 튜플 디자인 조합의 객체의 일부 기능적 특성을 통해 프로그램이 더 명확하고 명확하게 작동하도록 합니다.

포인터 유형

Rust에는 메모리 주소를 나타내는 여러 가지 유형이 있습니다.

이것이 러비시 컬렉션을 사용하는 대부분의 언어와 Rust의 주요 차이점입니다. Java에서 Rectangle 클래스에 Vector2D upperLeft; 필드가 포함된 경우, upperLeft는 별도로 생성된 다른 Vector2D 객체에 대한 참조입니다. Java에서 객체는 다른 객체의 실제 내용을 포함하지 않습니다.

하지만 Rust는 다릅니다. 이 언어는 메모리 할당을 최소한으로 유지하도록 설계되었습니다. 값은 기본적으로 중첩됩니다. ) 값은 4개의 인접한 정수로 저장됩니다. 이를 지역 변수에 저장하면 정수 너비의 4배에 해당하는 지역 변수를 얻게 됩니다. 힙에는 아무것도 할당되지 않습니다.

이는 메모리를 효율적으로 사용하는 데 도움이 될 수 있지만, Rust 프로그램에서 일부 값이 다른 값을 가리키도록 해야 할 때 포인터 유형을 명시적으로 사용해야 하는 대가를 치러야 합니다. 좋은 소식은 이러한 포인터 유형을 사용할 때 안전한 Rust에서는 정의되지 않은 동작을 제거하기 위해 포인터를 제한하므로, 포인터를 C++보다 Rust에서 올바르게 사용하기가 더 쉽다는 것입니다.

다음에서는 참조, 상자, 안전하지 않은 포인터의 세 가지 유형에 대해 설명합니다.

참조

유형이 &String인 값은 문자열 값에 대한 참조이고, &i32는 i32에 대한 참조입니다.

참조를 가장 간단하게 생각하는 방법은 Rust의 기본 포인터 유형으로 생각하면 됩니다. 런타임 중에 i32에 대한 참조는 스택이나 힙에 있을 수 있는 i32의 주소를 보유하는 기계어입니다. 표현식 &x는 x에 대한 참조를 생성하며, Rust 용어로는 참조를 빌린다고 합니다. 참조 r이 주어지면 *r 표현식은 r이 가리키는 값을 참조합니다. 이는 C와 C++의 & 및 * 연산자와 매우 유사하며, C의 포인터와 마찬가지로 참조는 범위를 벗어날 때 자동으로 리소스를 해제하지 않습니다.

그러나 C 포인터와 달리 Rust 참조는 절대 널이 아닙니다. 안전한 Rust에서는 널 참조를 생성할 수 있는 방법이 없습니다. C와 달리 Rust는 값의 소유권과 수명 주기를 추적하므로 댕글 포인터, 이중 릴리스, 포인터 실패와 같은 오류는 컴파일 시점에 미리 배제됩니다.

러스트 레퍼런스는 두 가지 형태로 제공됩니다.

&T

변경 불가능한 공유 참조. 특정 값에 대한 공유 참조를 동시에 여러 개 가질 수 있지만 읽기 전용이며, C의 const T*처럼 가리키는 값의 수정은 금지됩니다.

&mut T

변경 가능한 독점 참조입니다. C의 T*처럼 참조가 가리키는 값을 읽고 수정할 수 있습니다. 하지만 참조가 존재하는 한 해당 값에 대해 어떤 유형의 다른 참조도 가질 수 없습니다. 실제로 값에 액세스하는 유일한 방법은 변경 가능한 참조를 사용하는 것입니다.

Rust는 공유 참조와 변경 가능한 참조 사이에 "둘 중 하나" 메커니즘을 사용하여 "단일 작성자 또는 다중 독자" 규칙을 적용합니다. 값을 독점적으로 읽거나 쓸 수도 있고, 여러 명의 독자와 공유할 수도 있지만 둘 중 하나를 선택할 수는 없습니다. 컴파일 타임 검사로 시행되는 이 "둘 중 하나" 규칙은 Rust 보안의 핵심입니다. 5장에서는 안전한 참조를 사용하기 위한 Rust의 규칙을 설명합니다.

Box

힙에 값을 할당하는 가장 쉬운 방법은 Box:: new를 사용하는 것입니다:

let t = (12, "eggs");
let b = Box::new(t); // 힙에 튜플 할당하기

t의 유형은 (i32, &str)이므로 b의 유형은 Box<(i32, &str)>. Box:: new를 호출하면 힙에 이 튜플을 저장할 수 있는 충분한 메모리가 할당됩니다. b가 범위를 벗어나면 반환 등의 방법으로 b를 이동하지 않는 한 메모리는 즉시 해제됩니다. 이동은 4장에서 자세히 설명한 것처럼 Rust가 힙에 할당된 값을 처리하는 방식에 매우 중요합니다.

베어 포인터

Rust에는 베어 포인터 유형 *mut T와 *const T도 있습니다. 베어 포인터는 실제로 C++의 포인터와 매우 유사합니다. 베어 포인터를 사용하는 것은 안전하지 않은데, 그 이유는 Rust가 포인터가 가리키는 대상을 추적하지 않기 때문입니다. 예를 들어, 베어 포인터는 널이거나 해제되었거나 현재 다른 유형의 값을 포함하는 메모리를 가리킬 수 있습니다. C++의 모든 고전적인 포인터 버그가 "차용"될 수 있습니다.

그러나 안전하지 않은 블록에서는 베어 포인터만 참조 해제할 수 있습니다. 안전하지 않은 블록은 선택 사항인 Rust 고수준 언어 기능이며, 그 안전성은 사용자가 결정할 수 있습니다. 코드에 안전하지 않은 블록이 없는 경우에도 이 책에서 강조한 보안 보장은 여전히 유효합니다. 자세한 내용은 22장을 참조하세요.

주로 짧은 스케치로 구성된 문학의 한 유형입니다.

"자바스크립트 고급 프로그래밍"에는 포인터에 대한 별도의 소개가 없지만, 변수 참조값과 참조값의 특성에 포인터에 대한 언급이 있습니다.

참조 값은 힙 메모리에 저장된 객체입니다. 참조 값이 포함된 변수에는 실제로는 객체 자체가 아니라 해당 객체에 대한 포인터만 포함됩니다. 한 변수에서 다른 변수로 참조 값을 복사하면 포인터만 복사되므로 결과적으로 두 변수가 동일한 객체를 가리키게 됩니다.

Read next

React 테스트 라이브러리 테스트 시나리오

프론트엔드 React 테스트, React 테스트 라이브러리 일반적인 테스트 시나리오, Dom 테스트, 이벤트 테스트, 비동기 테스트

Oct 9, 2025 · 4 min read