logo MSJO.kr

Rust 2024(1.85.0) Async Closures

2025-09-03
MsJ
 

Rust는 1.85 버전 기점으로 2024 Edition 발표되었다. Rust Edition이 필요한 이유는 언어 안정성 유지, 프로젝트 간 호환성, 새로운 기능의 점진적인 도입, 개발 과정의 명확성 때문이다. Rust Edition은 2015(1.31.0 전), 2018(1.31.0), 2021(1.56.0), 2024(1.85.0)와 같이 출시 연도와 비슷하게 명명한다.

2024 Edition의 주요 특징은 공식문서에서 확인하고 여기에서는 주요 특징인 Async Closures에 대하여 간단한 예제와 더불어 C# 언어와 비교해 보았다.

Cargo.toml 선언
[package]  
name = "hello"  
version = "0.1.0"  
edition = "2024"  
  
[dependencies]  
tokio = { version = "1.47.1", features = ["time", "rt", "rt-multi-thread", "macros"] }
Async Closures 예제
// 동기 클로저
fn main() {  
    let add = |x, y| x + y;  
    let result = add(1, 2);  
    println!("{}", result);  
}

위의 동기 클로저와 비교한 아래의 예제는 비동기, 비동기 클로저에 대한 보기다.

// 2024 전
async fn add_async(x: i32, y: i32) -> i32 {  
    x + y  
}  
  
#[tokio::main]  
async fn main() {  
    let add = |x, y| add_async(x, y);  
    let future = add(1, 2).await;  
    println!("{}", future);  
}
// 2024 전
#[tokio::main]  
async fn main() {  
        let add = async move |x, y| x + y;  
        let result = add(1, 2).await;  
        println!("{}", result);  
}
// 2024 Async Closures
#[tokio::main]  
async fn main() {  
    let add = async |x, y| x + y;  
    let result = add(1, 2).await;  
    println!("{}", result);  
}
C#과 비교한 예제
async fn print_message() {  
    for i in 1..=3 {  
        println!("{}초", i);  
        tokio::time::sleep(tokio::time::Duration::from_millis(1000)).await;  
    }  
}  
  
#[tokio::main]  
async fn main() {  
    let async_closure = async |x: i32| -> i32 {  
        println!("Processing: {}", x);  
        tokio::time::sleep(tokio::time::Duration::from_millis(3000)).await;  
        x * 2  
    };  
  
   let a = tokio::join!(async_closure(5), print_message());  
  
    // print_message().await;  
    // let result = async_closure(5).await;    // println!("Result ====== : {}", result); // 출력: Result: 10  
    println!("Result : {}", a.0); // 출력: Result: 10  
}
using System;  
using System.Threading.Tasks;  
  
namespace TestAsync;  
  
internal class Program  
{  
    private static async Task Main()  
    {  
        Func<int, Task<int>> asyncClosure = async (x) =>  
        {  
            Console.WriteLine($"Processing: {x}");  
            await Task.Delay(TimeSpan.FromMilliseconds(3000));  
            return x * 2;  
        };  
  
        Task<int> processingTask = asyncClosure(5);  
        Task printingTask = PrintMessageAsync();
        // 러스트 tokio::join!
        await Task.WhenAll(processingTask, printingTask);  
        Console.WriteLine($"Result : {processingTask.Result}");  
    }  
  
    private static async Task PrintMessageAsync()  
    {  
        for (int i = 1; i <= 3; i++)  
        {  
            Console.WriteLine($"{i}초");  
            await Task.Delay(TimeSpan.FromMilliseconds(1000));  
        }  
    }  
}
C# 추가 예제
// 위의 C# 에제를 정규화 한 것이다.
using System;  
using System.Threading.Tasks;  
  
namespace TestAsync;  
  
internal class Program  
{  
    private static async Task Main()  
    {  
        Task<int> processingTask = AsyncClosure(5);  
        Task printingTask = PrintMessageAsync();  
        // 러스트 tokio::join!
        await Task.WhenAll(processingTask, printingTask);  
        Console.WriteLine($"Result : {processingTask.Result}");  
        return;  
    }  
  
    private static async Task<int> AsyncClosure(int x)  
    {  
        Console.WriteLine($"Processing: {x}");  
        await Task.Delay(TimeSpan.FromMilliseconds(3000));  
        return x * 2;  
    }  
      
    private static async Task PrintMessageAsync()  
    {  
        for (int i = 1; i <= 3; i++)  
        {  
            Console.WriteLine($"{i}초");  
            await Task.Delay(TimeSpan.FromMilliseconds(1000));  
        }  
    }  
}

위의 예제를 간단히 설명하면 처리 과정을 동시 처리하기 위해 1, 2, 3초 카운트를 표현하면서 3초 후에 결과가 나온다.


Prεv(Θld)   Nεxt(Nεw)
Content
Search     RSS Feed     BY-NC-ND