Rust - 타입 모음
Rust는 다양한 타입들이 있는데 처음 접하는 사람에게는 생각보다 생소할 수 있습니다. 이 글에서 집중적으로 조명해 볼게요.
Rust 맛보기
- 1. Rust - 입문하기
- 2. Rust - 타입 모음
- 3. Rust - Memory Ownership
- 4. Rust - Control Flow
- 5. Rust - Structured Data Types
- 6. Rust - Project Organization
- 7. Rust - Error Handling
- 8. Rust - Collections
- 9. Rust - Generics
- 10. Rust - Test Automation
- 11. Rust - Functional Programming
- 12. Rust - Memory Management
다양한 Scalar 타입들
Integer Literals
정수형 리터럴의 타입을 명시하거나, 표기 방식을 달리 할 수 있습니다.
let x = 57u8; // u8 타입의 57
let x = 98_222; // _를 사용해 숫자를 구분할 수 있음
let x = 0xff; // 16진수
let x = 0o77; // 8진수
let x = 0b1111_0000; // 2진수
let x = b'A'; // 바이트 리터럴 (u8 only)
타입별 associated function
println!("i8: MIN = {}, MAX = {}", i8::MIN, i8::MAX);
println!("i16: MIN = {}, MAX = {}", i16::MIN, i16::MAX);
println!("i32: MIN = {}, MAX = {}", i32::MIN, i32::MAX);
println!("i64: MIN = {}, MAX = {}", i64::MIN, i64::MAX);
println!("i128: MIN = {}, MAX = {}", i128::MIN, i128::MAX);
char
타입
Rust의 char
타입은 4바이트의 유니코드 스칼라 값입니다. C와 달리 이모지 등도 표현 가능합니다.
let c = 'z';
let z = 'ℤ';
let heart_eyed_cat = '😻';
Compound 타입들
Tuple 타입
다른 프로그래밍 언어와 마찬가지로 Tuple은 여러 개의 값이 하나로 묶여 있으며, 길이 변경이 불가합니다. 또한 heap allocation이 불필요하며 스택에 저장됩니다.
튜플의 타입을 명시할 때에는 멤버의 타입을 괄호 안에 표기하는 형태로 나타냅니다.
let tup: (i32, f64, u8) = (500, 6.4, 1);
println!("The value of y is: {}", tup.1);
위와 같이 .
을 사용해 튜플의 멤버에 접근할 수 있습니다.
Array 타입
튜플과 달리 배열의 모든 요소는 같은 타입을 가져야 합니다(C처럼).
또한 한번 선언되면 길이를 변경할 수 없습니다.
문법은 파이썬의 리스트와 유사합니다.
let a = [1, 2, 3, 4, 5];
let a: [i32; 5] = [1, 2, 3, 4, 5]; // 타입 명시: i32 타입의 5개 요소를 가지는 배열
let a = [3; 5]; // [3, 3, 3, 3, 3]
참고로 Rust는 배열에 대한 잘못된 접근을 컴파일 타임에 검출할 수 있는 강력한 기능을 제공합니다.
또한 런타임에도 범위를 벗어난 접근을 검출할 수 있습니다(유저가 입력한 인덱스가 배열의 길이를 넘어가는 경우 등).
문자열 타입: &str
과 String
str
는 UTF-8로 인코딩된 문자열 슬라이스이며, 스트링 리터럴의 경우 data 섹션에 저장됩니다. &str
는 이 str
의 시작 주소와 길이를 담고 있는 String Slice에 해당합니다.
str
는 그대로 다룰 수 없고, 반드시 &str
로만 접근할 수 있습니다.
&str
는 C/C++에서의 const char*
와 비슷한 역할을 한다고 이해해도 좋습니다.
타입 명시 없이 큰따옴표로 작성하는 스트링 리터럴은 &str
타입을 갖는, String Slice입니다.
String
은 heap에 할당되는 UTF-8 인코딩 문자열입니다.
(여기 써있는 말이 이해가 안 되면 메모리 소유권 개념을 숙지한 후 다시 읽어 보세여)정확히는 String
을 생성할 때, str
이 heap에 할당되어 이 heap에 할당된 str
을 소유하는 String
이 생성됩니다. 메모리 소유권 규칙에 따르면, String
은 str
의 소유권을 갖고 있으므로 str
에 대한 reference는 동시에 존재할 수 있습니다.
&str
과 달리 String
타입은 문자열의 시작 주소와 길이뿐 아니라 capacity도 가지고 있습니다. String
타입은 문자열의 길이를 확장할 수 있는 growable한 특성이 있습니다.
let mut s = String::from("hello");
s.push_str(", world!"); // push_str()은 문자열 슬라이스(&str)를 인자로 받음, 이때 length와 capacity 값이 변함
println!("{}", s); // "hello, world!"
Collections
Collection에 관해서는 분량이 방대한 관계로 별도 게시글에서 따로 다룰 거예여
참고 문헌
-
고려대학교 컴퓨터학과 오상은 교수님의 시스템 프로그래밍(COSE322) 과목 강의자료
Rust 맛보기