출시·고도화 중
Rust 안내서 · 3/6
Rust는 정적 타입 언어입니다. 모든 값의 타입이 컴파일 시점에 정해지며, 서로 다른 숫자 타입끼리도 자동으로 바뀌지 않습니다. 이 장에서는 기본 타입, 문자열, 구조체와 열거형, 자주 쓰는 컬렉션, 그리고 null 대신 쓰는 Option을 살펴봅니다.
| 분류 | 타입 | 설명 |
|---|---|---|
| 부호 있는 정수 | i8 i16 i32 i64 i128 isize | 기본값은 i32 |
| 부호 없는 정수 | u8 u16 u32 u64 u128 usize | 인덱스와 길이는 usize |
| 실수 | f32 f64 | 기본값은 f64 |
| 논리 | bool | true 또는 false |
| 문자 | char | 유니코드 스칼라 값 하나(4바이트) |
정수 오버플로는 디버그 빌드에서 패닉을 일으키고, 릴리스 빌드에서는 기본적으로 값이 순환합니다. 의도를 분명히 하려면 checked_add, wrapping_add, saturating_add 같은 메서드를 씁니다. 타입 변환은 as로 명시합니다.
fn main() {
let a: i32 = -42;
let b: u8 = 255;
let c = 3.14_f64;
let ok: bool = true;
let heart: char = '♥';
println!("{a} {b} {c} {ok} {heart}");
println!("{:?}", b.checked_add(1)); // None: 넘치면 None
println!("{}", b.wrapping_add(1)); // 0: 한 바퀴 돌아감
println!("{}", b.saturating_add(1)); // 255: 최댓값에서 멈춤
let n = 300_i32 as u8; // 44: as 는 잘라 냅니다
let avg = (7 as f64) / 2.0; // 3.5
println!("{n} {avg}");
}튜플은 서로 다른 타입을 고정된 개수만큼 묶고, 배열은 같은 타입을 고정된 길이만큼 담습니다. 길이가 변하는 목록은 뒤에서 볼 Vec을 씁니다.
fn main() {
let point: (i32, f64, char) = (1, 2.5, 'x');
let (x, y, z) = point; // 구조 분해
println!("{x} {y} {z} / 첫 요소 {}", point.0);
let nums = [1, 2, 3, 4, 5];
let zeros = [0u8; 4]; // 0 을 네 개
let slice = &nums[1..3]; // [2, 3]
println!("{} {:?} {:?}", nums.len(), zeros, slice);
}배열 인덱스가 범위를 벗어나면 정의되지 않은 동작 대신 패닉이 납니다. 안전하게 읽으려면 nums.get(10)처럼 Option을 돌려주는 메서드를 씁니다.
Rust의 문자열은 두 가지입니다. String은 힙에 저장되고 크기를 바꿀 수 있는 소유된 문자열이며, &str은 어딘가에 있는 UTF-8 문자열을 빌려 보는 조각입니다. 문자열 리터럴은 &'static str입니다. 함수 매개변수는 보통 &str로 받으면 두 종류를 모두 넘길 수 있습니다.
fn greet(name: &str) -> String {
format!("안녕하세요, {name}님")
}
fn main() {
let literal: &str = "Rust";
let mut owned = String::from("Hello");
owned.push_str(", world");
owned.push('!');
println!("{}", greet(literal));
println!("{}", greet(&owned)); // &String 이 &str 로 자동 변환됩니다
let part: &str = &owned[0..5]; // "Hello"
println!("{part}");
// len() 은 바이트 수, 글자 수는 chars().count()
println!("{} {}", "한글".len(), "한글".chars().count()); // 6 2
}문자열은 UTF-8이므로 s[0]처럼 정수 하나로 인덱싱할 수 없습니다. 글자 단위로 다룰 때는 chars()를 쓰고, 범위로 자를 때는 글자 경계를 지켜야 합니다.
구조체는 관련된 데이터를 이름 붙은 필드로 묶습니다. 메서드는 impl 블록에 정의하며, 첫 매개변수 &self는 읽기, &mut self는 수정을 뜻합니다. self가 없는 new 같은 함수는 연관 함수라 하며 Rect::new로 부릅니다.
#[derive(Debug, Clone, PartialEq)]
struct Rect {
width: u32,
height: u32,
}
impl Rect {
fn new(width: u32, height: u32) -> Self {
Self { width, height }
}
fn area(&self) -> u32 {
self.width * self.height
}
fn scale(&mut self, k: u32) {
self.width *= k;
self.height *= k;
}
}
fn main() {
let mut r = Rect::new(3, 4);
println!("넓이 {}", r.area()); // 12
r.scale(2);
println!("{r:?}"); // Rect { width: 6, height: 8 }
}열거형은 "여러 가지 중 하나"를 표현하며, 각 경우가 서로 다른 데이터를 가질 수 있습니다. match와 함께 쓰면 모든 경우를 빠짐없이 처리하게 됩니다.
enum Shape {
Circle { radius: f64 },
Square(f64),
Point,
}
fn area(shape: &Shape) -> f64 {
match shape {
Shape::Circle { radius } => std::f64::consts::PI * radius * radius,
Shape::Square(side) => side * side,
Shape::Point => 0.0,
}
}
fn main() {
let shapes = [Shape::Circle { radius: 1.0 }, Shape::Square(2.0), Shape::Point];
for s in &shapes {
println!("{:.2}", area(s));
}
}Rust에는 null이 없습니다. 값이 없을 수 있으면 Option<T>를 씁니다. Some(값) 또는 None이며, 꺼내 쓰기 전에 반드시 두 경우를 처리해야 하므로 null 참조 오류가 생기지 않습니다.
use std::collections::HashMap;
fn main() {
let mut scores: Vec<i32> = Vec::new();
scores.push(80);
scores.push(95);
let total: i32 = scores.iter().sum();
println!("{scores:?} 합계 {total}");
println!("{:?}", scores.get(5)); // None
let text = "the cat the dog the end";
let mut counts: HashMap<&str, usize> = HashMap::new();
for word in text.split_whitespace() {
*counts.entry(word).or_insert(0) += 1;
}
match counts.get("the") {
Some(n) => println!("the: {n}번"), // 3번
None => println!("없음"),
}
let birds = counts.get("bird").copied().unwrap_or(0);
println!("bird: {birds}번"); // 0번
}Vec<T>는 길이가 변하는 배열이고 vec![1, 2, 3] 매크로로도 만들 수 있습니다. HashMap<K, V>는 키로 값을 찾는 표이며, entry API를 쓰면 "없으면 넣고 있으면 고치기"를 한 줄로 쓸 수 있습니다. Option에는 map, unwrap_or, and_then 같은 메서드가 많아 match 없이도 간결하게 다룰 수 있습니다.
as로 명시합니다.String은 소유된 문자열, &str은 빌려 보는 문자열 조각입니다. 매개변수는 &str로 받습니다.impl 메서드를, 열거형은 "여러 경우 중 하나"를 표현합니다.Vec와 HashMap이 가장 많이 쓰는 컬렉션이며, 없을 수 있는 값은 Option으로 다룹니다.
댓글 0개
로그인 · 로그인하면 댓글을 남길 수 있습니다.
첫 댓글을 남겨 보세요.