상세 컨텐츠

본문 제목

4. Rust 데이터 유형

Rust를 처음부터 배우세요

by 러스트코리아 2024. 11. 13. 22:14

본문

반응형

유형 시스템은 언어가 지원하는 다양한 유형의 값을 구현하기 때문에 모든 언어의 핵심입니다.

유형  시스템은 IT 초보자들에게 가장 어려운 3대 산 중 하나이기도 하다.

유형  시스템이 이해하기 어려운 주된 이유는 적절한 참조 시스템이 없기 때문이다.

예를 들어, 유형 시스템 의 목적 은 프로그램이 숫자를 저장하거나 연산하기 전에 숫자의 유효성을 확인하는 것이라고 가정해 보겠습니다 .

이 문장만으로도 너무나 단순해서 모든 단어가 이해되는 것 같습니다. 

유형 시스템은 제공된 값이 프로그램에 의해 저장되거나 조작되기 전에 해당 값의 유효성을 확인합니다.

이렇게 하면 프로그램이 실행될 때 변수에 제공된 데이터에 유형 오류가 발생하지 않습니다.

한 단계 더 나아가, 유형 시스템을 사용하면 편집자가 오류를 보고하거나 자동으로 메시지를 표시할 수 있습니다.

Rust는 정적이고 엄격한 유형의 언어입니다. 각 값에는 정수, 부동 소수점 등 고유한 데이터 유형이 있습니다.

Rust 언어에서는 값을 할당할 때 변수의 데이터 유형을 지정할 필요가 없습니다. Rust 컴파일러는 할당된 값을 기반으로 변수의 데이터 유형을 자동으로 추론할 수 있습니다.

4.1 변수 선언/정의

Rust 언어는 변수를 선언하고 정의하기 위해 let 키워드를 사용합니다.

Rust 언어에서 변수를 선언하는 구문 형식은 다음과 같습니다.

  1. let variable_name = value;
  2. let 변수명 = 값;

여기서는 변수의 정의와 선언에 대해서만 간략하게 다루고, 다음 장에서 자세히 소개하겠습니다.

아래 코드는 변수를 정의하는 방법을 보여줍니다.

  1. fn main() {
  2. let company_string = "TutorialsPoint"; // 문자열 유형
  3. let rating_float = 4.5; // float 유형
  4. let is_growing_boolean = true; // boolean 유형
  5. let icon_char = '♥'; //unicode character 유형(유니코드 문자 유형)
  6.  
  7. println!("company name is:{}",company_string);
  8. println!("company rating on 5 is:{}",rating_float);
  9. println!("company is growing :{}",is_growing_boolean);
  10. println!("company icon is:{}",icon_char);
  11. }

위 코드에서는 각 변수의 데이터 유형을 지정하지 않았습니다. Rust 컴파일러는 등호 = 오른쪽에 있는 값에서 변수 유형을 자동으로 추론합니다 . 예를 들어 Rust는 큰따옴표 로 묶인 데이터를 string 으로 , 소수점이 없는 숫자를 정수 로 자동 추론합니다 . True 또는 False 값을 Boolean 유형 으로 추론합니다 .

println!()은 함수가 아닌 매크로입니다. 함수와 매크로를 구별하는 유일한 방법은 함수 이름/매크로 이름 끝에 느낌표(!)가 있는지 확인하는 것입니다. 그것은 매크로이고, 그렇지 않다면 함수입니다.

println!() 매크로는 두 가지 매개변수를 허용합니다:

  • 첫 번째 매개변수는 포맷터(보통 {})입니다. 복합 유형인 경우에는 {:?}입니다.
  • 두 번째 매개변수는 변수 이름 또는 상수 이름입니다.

위의 Rust 코드를 컴파일하고 실행하면 출력 결과는 다음과 같습니다.

  1. company name is: TutorialsPoint
  2. company rating on 5 is:4.5
  3. company is growing: true
  4. company icon is:

4.2 스칼라 데이터 유형

스칼라 데이터 유형은 기본 데이터 유형이라고도 합니다. 스칼라 데이터 유형은 10, 3.14 또는 c와 같은 단일 값만 저장할 수 있습니다.

Rust 언어에는 네 가지 스칼라 데이터 유형이 있습니다.

  • 정수
  • 부동 소수점
  • 부울 유형
  • 문자 유형

다음으로 각 스칼라 데이터 유형에 대해 간략하게 소개하겠습니다.

4.3 정수형

정수는 0, 1, -1, -2, 9999999 등과 같이 소수점이 없는 숫자이지만 0.0, 1.0, -1.11 등은 정수가 아닙니다.

정수형은 모든 숫자를 포함할 수 있지만 무한할 수는 없지만 충분히 사용할 수 있습니다.

가장 큰 정수 유형은 std::u128:MAX로 정의된 340282366920938463463374607431768211455입니다.

가장 작은 정수는 -170141183460469231731687303715884105728이며 std::i128:MIN으로 정의됩니다.

천문학적인 숫자처럼 보이나요?

정수는 부호 있는 정수  부호 없는 정수의 두 가지 유형 으로 더 나눌 수 있습니다 .

  • 부호 있는 정수형(영문 부호 있음)은 양수와 음수를 모두 저장할 수 있습니다.
  • 부호 없는 정수형은 부호가 없기 때문에 양수만 저장할 수 있습니다.

저장 공간의 측면에서 정수는 1바이트, 2바이트, 4바이트, 8바이트, 16바이트로 더 나눌 수 있습니다.

1바이트 = 8비트, 각 비트는 이진수 0 또는 1만 저장할 수 있으므로 각 바이트가 저장할 수 있는 최대 수는 256이고 최소 수는 -127입니다.

좀 복잡할 수도 있는데, C 언어 데이터를 자세히 살펴보는 것이 더 쉬울 수도 있습니다.

다음 표에는 정수의 모든 세분화 유형이 나열되어 있습니다.

 

크기 정의됨 정의되지않은
8비트 i8 u8
16비트 i16 u16
32비트 i32 u32
64비트 i64 u64
128비트 i128 u128
Arch isize usize

i32는 기본 정수 유형입니다. 데이터 유형을 말하지 않고 숫자를 직접 말하면 기본값은 i32입니다.

정수 유형의 길이는 아치형일 수도 있습니다. 아치는 CPU 아키텍처에 따라 크기가 결정되는 정수 유형입니다.

Arch 크기의 정수는 x86 시스템에서는 32비트이고 x64 시스템에서는 64비트입니다.

Arch 정수는 컨테이너나 배열의 크기 또는 데이터가 저장되는 메모리의 위치를 ​​나타내는 데 자주 사용됩니다.

4.3.1 예: 다양한 정수형의 변수를 정의하는 방법

정수형 변수를 정의할 때, 각 정수형의 최대값과 최소값에 주의하세요. 이를 초과할 경우 할당이 실패할 수 있으며, 원하는 결과가 나오지 않을 수도 있습니다.

  1. fn main() {
  2. let result = 10; // i32 기본
  3. let age:u32 = 20;
  4. let sum:i32 = 5-15;
  5. let mark:isize = 10;
  6. let count:usize = 30;
  7. println!("result value is {}",result);
  8. println!("sum is {} and age is {}",sum,age);
  9. println!("mark is {} and count is {}",mark,count);
  10. }

위의 Rust 코드를 컴파일하고 실행하면 출력 결과는 다음과 같습니다.

  1. result value is 10
  2. sum is -10 and age is 20
  3. mark is 10 and count is 30

정수형은 정수만 저장할 수 있고, 소수점 이하가 모두 0이더라도 소수점이 있는 숫자는 저장할 수 없습니다. 정수에 10진수를 할당하면 컴파일 오류가 보고됩니다.

  1. fn main() {
  2.   let age:u32 = 20.0;
  3. }

위의 Rust 코드를 컴파일하고 실행하면 오류 메시지는 다음과 같습니다.

  1. error[E0308]: mismatched types
  2. --> src/main.rs:2:18
  3. |
  4. 2 | let age:u32 = 20.0;
  5. | ^^^^ expected u32, found floating-point number
  6. |
  7. = note: expected type `u32`
  8. found type `{float}`

오류 메시지에서 볼 수 있듯이 Rust 언어는 20.0 부동 소수점 숫자와 같은 소수점을 사용하여 숫자를 호출합니다.

표현하려면 float를 사용하세요. u32 유형에는 float 유형 번호를 할당할 수 없습니다.

4.3.2 정수 범위

모든 정수 유형이 임의의 숫자를 저장할 수 있는 것은 아닙니다. 각 정수 유형은 고정된 크기의 숫자만 저장할 수 있지만 일반적으로 큰 정수 유형은 작은 정수 유형을 저장할 수 있습니다.

 부호 있는 정수 유형이 저장할 수 있는 최소값은 -(2^(n-1)) 이고, 저장할 수 있는 최대값은 2^(n-1) -1 입니다 .

 부호 없는 정수형이 저장할 수 있는 최소값은 0 이고 , 저장할 수 있는 최대값은 2^n - 1 입니다 .

여기서 n은 데이터 유형의 크기를 나타냅니다.

예를 들어, 8비트 부호 있는 정수 i8의 경우 저장할 수 있는 최소값은 -(2^(8-1)) = -128입니다. 최대값은 (2^(8-1)-1) = 127입니다.

예를 들어, 8비트 부호 없는 정수 유형 u8의 경우 저장할 수 있는 최소값은 0이고 저장할 수 있는 최대값은 2^8-1 = 255입니다.

4.3.3 정수 오버플로

모든 정수 유형이 숫자를 저장할 수 있는 것은 아닙니다. 각 정수 유형은 고정된 크기의 숫자만 저장할 수 있습니다. 주어진 숫자가 정수형의 범위를 벗어나면 오버플로가 발생합니다.

예를 들어 i8이 저장할 수 있는 최소값은 0입니다. -1을 저장하면 오버플로가 발생합니다.

데이터 오버플로가 발생하면 Rust는 데이터 오버플로를 나타내는 오류를 발생시킵니다.

예를 들어, 다음 코드를 컴파일하면 오류가 보고됩니다.

  1. fn main() {
  2. let age:u8 = 255;
  3.  
  4. // u8은 0부터 255까지만 저장할 수 있습니다.
  5. let weight:u8 = 256; // 오버플로 값은 0입니다.
  6. let height:u8 = 257; // 오버플로 값은 1입니다.
  7. let score:u8 = 258; // 오버플로 값은 2입니다.
  8.  
  9. println!("age is {} ",age);
  10. println!("weight is {}",weight);
  11. println!("height is {}",height);
  12. println!("score is {}",score);
  13. }

위의 코드를 컴파일하고 실행하면 오류 메시지는 다음과 같습니다.

  1. error: literal out of range for u8
  2. --> src/main.rs:5:20
  3. |
  4. 5 | let weight:u8 = 256;
  5. | ^^^
  6. |
  7. = note: #[deny(overflowing_literals)] on by default
  8.  
  9. error: literal out of range for u8
  10. --> src/main.rs:6:20
  11. |
  12. 6 | let height:u8 = 257;
  13. | ^^^
  14.  
  15. error: literal out of range for u8
  16. --> src/main.rs:7:19
  17. |
  18. 7 | let score:u8 = 258;
  19. | ^^^

오류 메시지를 보면 세 곳의 오버플로 위치에서 오류가 보고되었습니다. 할당된 번호가 u8 범위를 초과한다는 메시지가 나타납니다.

4.4 부동 소수점 유형: f32 및 f64

앞서 언급했듯이 정수는 소수점 없이 숫자만 저장할 수 있습니다. 소수점이 있는 숫자의 경우 Rust는 부동 소수점 유형을 제공합니다.

Rust가 정수와 부동 소수점 유형을 구별하는 유일한 지표는 소수점의 유무 입니다 .

Rust의 정수와 부동 소수점 유형은 엄격하게 구별되며 서로 변환할 수 없습니다.

즉, 어떤 정수 유형에도 0.0을 할당할 수 없으며 부동 소수점 유형에 0을 할당할 수도 없습니다.

저장 크기에 따라 부동 소수점 유형을 f32  f64 로 나눕니다 . 여기서 f64는 기본 부동 소수점 유형입니다.

  • f32는 단정밀도 부동 소수점 유형이라고도 합니다.
  • 배정밀도 부동 소수점 유형으로도 알려진 f64는 Rust의 기본 부동 소수점 유형입니다.

4.3.1 예: 다양한 부동 소수점 변수를 정의하는 방법

부동소수점 변수를 정의할 때, 각 부동소수점 타입의 최대값과 최소값에 주의하세요. 이를 초과할 경우 할당이 실패할 수 있으며, 원하는 결과가 나오지 않을 수도 있습니다.

  1. fn main() {
  2. let result = 10.00; // 기본값은 f64입니다.
  3. let interest:f32 = 8.35;
  4. let cost:f64 = 15000.600; //  부동 소수점
  5.  
  6. println!("result value is {}",result);
  7. println!("interest is {}",interest);
  8. println!("cost is {}",cost);
  9. }

위의 Rust 코드를 컴파일하고 실행하면 오류 메시지는 다음과 같습니다.

  1. interest is 8.35
  2. cost is 15000.6

4.4 자동 유형 변환은 허용되지 않습니다.

Rust와 C/C++의 숫자 유형 간의 차이점은 Rust 언어가 자동 유형 변환을 허용하지 않는다는 것입니다.

예를 들어, 부동 소수점 유형에 정수를 할당하면 오류가 발생합니다.

4.4.1 예

  1. fn main() {
  2. let interest:f32 = 8; // integer assigned to float variable
  3. println!("interest is {}",interest);
  4. }

위 코드를 컴파일하면 일치하지 않는 유형 오류 오류가 발생합니다.

  1. error[E0308]: mismatched types
  2. --> main.rs:2:22
  3. |
  4. 2 | let interest:f32=8;
  5. | ^ expected f32, found integral variable
  6. |
  7. = note: expected type `f32`
  8. found type `{integer}`
  9. error: aborting due to previous error(s)

4.5 숫자 가독성 구분 기호 _

매우 큰 숫자를 쉽게 읽을 수 있도록 Rust 언어에서는 가상 구분 기호 , 즉 밑줄(_)을 사용하여 가독성을 위해 숫자를 구분합니다. 예를 들어 50000의 가독성을 향상시키기 위해 50_000으로 쓸 수 있습니다.

Rust 언어는 컴파일 타임에 숫자 가독성 구분 기호 _를 제거합니다.

4.5.1 예

숫자 구분 기호를 보여주기 위해 몇 가지 예를 작성해 보겠습니다. 결과를 보면 구분 기호가 숫자에 아무런 영향을 미치지 않는다는 것을 알 수 있습니다.

  1. fn main() {
  2. let float_with_separator = 11_000.555_001;
  3. println!("float value {}",float_with_separator);
  4.  
  5. let int_with_separator = 50_000;
  6. println!("int value {}",int_with_separator);
  7. }

위의 코드를 컴파일하고 실행하면 출력 결과는 다음과 같습니다.

  1. float value 11000.555001
  2. int value 50000

4.6 부울 유형 boolean

Boolean 유형에는 true 또는 false의 두 가지 값만 사용할 수 있습니다.

Rust는 boolean 유형 의 변수를 선언하기 위해 bool 키워드를 사용합니다 .

4.6.1 예

  1. fn main() {
  2. let isfun:bool = true;
  3. println!("Is Rust Programming Fun ? {}",isfun);
  4. }

위의 코드를 컴파일하고 실행하면 출력 결과는 다음과 같습니다.

  1. Is Rust Programming Fun ? true

4.7 문자형 char

간단히 말해서 문자는 개별 문자 또는 단어인 문자열의 기본 구성 요소입니다.

Rust는 문자 데이터 유형으로 char을 사용합니다. 이는 C/C++에서 상속되었다고 할 수 있습니다.

그러나 C/C++와의 차이점은 Rust가 기본 인코딩으로 ASCII를 일반적으로 사용하는 대신 UTF-8을 기본 인코딩으로 사용한다는 것입니다.

즉, Rust의 문자 데이터 유형에는 숫자, 문자, 유니코드 및 기타 특수 문자가 포함됩니다.

Rust가 기본 인코딩으로 UTF-8을 선택한 것은 시대의 추세와 일치합니다. 프로그래밍과 인터넷이 더 이상 라틴어권 국가에만 국한되지 않았기 때문에 중국, 인도, 일본과 같은 국가에는 수많은 프로그래머와 인터넷 사용자가 있습니다.

유니코드로 인코딩된 스칼라 값의 범위는 U+0000 ~ U+D7FF, U+E000 ~ U+10FFFF(포함)입니다.

4.7.1 예

우리는 Rust의 char 문자 유형을 보여주기 위해 여러 다른 언어의 문자를 출력합니다.

  1. fn main() {
  2. let special_character = '@'; //default
  3. let alphabet:char = 'A';
  4. let emoji:char = 'c'; //  
  5.  
  6. println!("special character is {}",special_character);
  7. println!("alphabet is {}",alphabet);
  8. println!("emoji is {}",emoji);
  9. }

위의 코드를 컴파일하고 실행하면 출력 결과는 다음과 같습니다.

  1. special character is @
  2. alphabet is A
  3. emoji is c
현재 콘텐츠 저작권은 chapin666 또는 그 계열사에 있습니다.
반응형

'Rust를 처음부터 배우세요' 카테고리의 다른 글

6. Rust 상수  (0) 2024.11.13
5. Rust 변수 정의  (0) 2024.11.13
3. Rust Hello-World  (0) 2024.11.13
2. Rust 개발 환경 구성  (0) 2024.11.13
1. Rust 언어 소개  (0) 2024.11.13

관련글 더보기