Rust는 안전성과 성능을 보장하면서도 다양한 고급 기능을 제공합니다. \
Rust의 고급 기능 중 몇 가지를 설명합니다: 제네릭, 트레잇, 라이프타임, 매크로, 그리고 비동기 프로그래밍.
제네릭은 함수, 구조체, 열거형 등을 정의할 때 구체적인 타입을 지정하지 않고, 다양한 타입을 처리할 수 있도록 합니다.
fn largest<T: PartialOrd>(list: &[T]) -> &T {
let mut largest = &list[0];
for item in list {
if item > largest {
largest = item;
}
}
largest
}
fn main() {
let number_list = vec![34, 50, 25, 100, 65];
let result = largest(&number_list);
println!("The largest number is {}", result);
let char_list = vec!['y', 'm', 'a', 'q'];
let result = largest(&char_list);
println!("The largest char is {}", result);
}
위 예제에서 largest 함수는 제네릭 타입 T를 사용하여 다양한 타입의 리스트에서 가장 큰 값을 찾습니다. T: PartialOrd는 T가 비교 가능한 타입임을 나타냅니다.
트레잇은 객체의 동작을 정의하는 인터페이스입니다. 트레잇을 사용하여 구조체에 공통된 동작을 구현할 수 있습니다.
trait Summary {
fn summarize(&self) -> String;
}
struct Article {
headline: String,
content: String,
}
impl Summary for Article {
fn summarize(&self) -> String {
format!("{}: {}", self.headline, self.content)
}
}
fn main() {
let article = Article {
headline: String::from("Rust is great!"),
content: String::from("Rust is a systems programming language..."),
};
println!("New article available! {}", article.summarize());
}
위 예제에서 Summary 트레잇을 정의하고, Article 구조체에 대해 이를 구현했습니다. summarize 메서드는 Article의 요약을 반환합니다.
라이프타임은 참조자가 유효한 범위를 명시적으로 지정하여 메모리 안전성을 보장합니다.
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
fn main() {
let string1 = String::from("long string is long");
let string2 = String::from("xyz");
let result = longest(&string1, &string2);
println!("The longest string is {}", result);
}
위 예제에서 longest 함수는 두 문자열 참조를 받아서 더 긴 문자열 참조를 반환합니다. 'a 라이프타임 매개변수는 반환되는 참조가 입력 참조들 중 하나와 동일한 라이프타임을 가짐을 보장합니다.
매크로는 코드 생성을 자동화하는 강력한 도구입니다. 매크로는 반복적인 코드 작성을 줄이고, 코드의 가독성과 유지보수성을 높입니다.
macro_rules! say_hello {
() => {
println!("Hello!");
};
}
fn main() {
say_hello!();
}
위 예제에서 macro_rules!를 사용하여 say_hello 매크로를 정의했습니다. say_hello! 매크로를 호출하면 "Hello!"를 출력합니다.
Rust는 async와 await 키워드를 사용하여 비동기 프로그래밍을 지원합니다. 비동기 프로그래밍은 I/O 작업과 같은 시간이 오래 걸리는 작업을 효율적으로 처리할 수 있게 합니다.
use tokio::time::{sleep, Duration};
async fn say_hello() {
sleep(Duration::from_secs(1)).await;
println!("Hello, world!");
}
#[tokio::main]
async fn main() {
say_hello().await;
}
위 예제에서 async fn을 사용하여 비동기 함수를 정의하고, await 키워드를 사용하여 비동기 작업이 완료될 때까지 기다립니다. tokio 크레이트를 사용하여 비동기 런타임을 제공합니다.
Unsafe Rust: 안전하지 않은 Rust 코드 작성하기
let address = 0x012345usize;
let r = address as *const i32;unsafe fn dangerous() {}
unsafe { dangerous(); }static HELLO_WORLD: &str = "Hello, world!";
static mut COUNTER: u32 = 0;extern "C" {
fn abs(input: i32) -> i32;
}고급 트레잇: 트레잇의 고급 기능 활용하기
pub trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
}trait Display<T = Self> {
fn display(&self) -> String;
}trait Animal {
fn baby_name() -> String;
}
<Dog as Animal>::baby_name()고급 타입: 특수한 타입 시스템 기능
type Kilometers = i32;
type Thunk = Box<dyn Fn() + Send + 'static>;fn bar() -> ! {
panic!("이 함수는 절대 반환되지 않습니다");
}let s1: &str = "Hello there!";
let s2: Box<dyn Display> = Box::new(3);고급 함수와 클로저: 함수형 프로그래밍 기능
type F = fn(i32) -> i32;
let f: F = |x| x + 1;fn returns_closure() -> Box<dyn Fn(i32) -> i32> {
Box::new(|x| x + 1)
}매크로: 메타프로그래밍 도구
macro_rules! vec {
( $( $x:expr ),* ) => {
{
let mut temp_vec = Vec::new();
$(
temp_vec.push($x);
)*
temp_vec
}
};
}#[proc_macro]
pub fn make_answer(_item: TokenStream) -> TokenStream {
"fn answer() -> u32 { 42 }".parse().unwrap()
}참조: https://doc.rust-lang.org/book/ch19-00-advanced-features.html