मैं Rust में एक async फ़ंक्शन को मानचित्र में कैसे डाल सकता हूं?


11

जब मैं के लिए एक async रूटर लिख रहा हूँ मैं async कार्यों को संभाल नहीं सकते hyper

यह कोड:

use std::collections::HashMap;
use std::future::Future;

type BoxedResult<T> = Result<T, Box<dyn std::error::Error + Send + Sync>>;
type CalcFn = Box<dyn Fn(i32, i32) -> dyn Future<Output = BoxedResult<i32>>>;

async fn add(a: i32, b: i32) -> BoxedResult<i32> {
    Ok(a + b)
}

async fn sub(a: i32, b: i32) -> BoxedResult<i32> {
    Ok(a - b)
}

fn main() {
    let mut map: HashMap<&str, CalcFn> = Default::default();
    map.insert("add", Box::new(add));
    map.insert("sub", Box::new(sub));

    println!("map size: {}", map.len());
}

निम्न कंपाइलर त्रुटि उत्पन्न करता है:

error[E0271]: type mismatch resolving `<fn(i32, i32) -> impl std::future::Future {add} as std::ops::FnOnce<(i32, i32)>>::Output == dyn std::future::Future<Output = std::result::Result<i32, std::boxed::Box<dyn std::error::Error + std::marker::Send + std::marker::Sync>>>`
  --> src/main.rs:17:23
   |
17 |     map.insert("add", Box::new(add));
   |                       ^^^^^^^^^^^^^ expected opaque type, found trait std::future::Future
   |
   = note: expected type `impl std::future::Future`
              found type `dyn std::future::Future<Output = std::result::Result<i32, std::boxed::Box<dyn std::error::Error + std::marker::Send + std::marker::Sync>>>`
   = note: required for the cast to the object type `dyn std::ops::Fn(i32, i32) -> dyn std::future::Future<Output = std::result::Result<i32, std::boxed::Box<dyn std::error::Error + std::marker::Send + std::marker::Sync>>>`

error[E0271]: type mismatch resolving `<fn(i32, i32) -> impl std::future::Future {sub} as std::ops::FnOnce<(i32, i32)>>::Output == dyn std::future::Future<Output = std::result::Result<i32, std::boxed::Box<dyn std::error::Error + std::marker::Send + std::marker::Sync>>>`
  --> src/main.rs:18:23
   |
18 |     map.insert("sub", Box::new(sub));
   |                       ^^^^^^^^^^^^^ expected opaque type, found trait std::future::Future
   |
   = note: expected type `impl std::future::Future`
              found type `dyn std::future::Future<Output = std::result::Result<i32, std::boxed::Box<dyn std::error::Error + std::marker::Send + std::marker::Sync>>>`
   = note: required for the cast to the object type `dyn std::ops::Fn(i32, i32) -> dyn std::future::Future<Output = std::result::Result<i32, std::boxed::Box<dyn std::error::Error + std::marker::Send + std::marker::Sync>>>`

ऐसा लगता है कि आपस में संघर्ष है impl Futureऔर dyn Future, लेकिन मुझे नहीं पता कि इसे कैसे संभालना है।

जवाबों:


5

ऐसा इसलिए होता है क्योंकि impl Futureएक ठोस प्रकार होता है जबकि dyn Futureएक अमूर्त प्रकार होता है। HashMapअमूर्त प्रकार की अपेक्षा करता है क्योंकि यह केवल एक ही प्रकार के उदाहरण प्रस्तुत कर सकता है।

यदि हम async फ़ंक्शंस के रिटर्न प्रकार को बॉक्स कर सकते हैं, तो हम इन फ्यूचर्स को a में जोड़ पाएंगे HashMap

पहले हमें इसके प्रकार को बदलने की आवश्यकता है CalcFn:

type CalcFn = Box<dyn Fn(i32, i32) -> Pin<Box<dyn Future<Output = i32>>>>;

तो यह चाल कर सकते हैं:

let mut map: HashMap<&str, CalcFn> = Default::default();
map.insert("add", Box::new(|a, b| Box::pin(add(a, b))));
map.insert("sub", Box::new(|a, b| Box::pin(sub(a, b))));

println!("map size: {}", map.len());

//map.get("add").unwrap()(2, 3).await

यह पूर्ण उदाहरण सरलीकृत Futureहै Item, प्रकार एक का उपयोग कर i32एक के बजाय Result। कृपया अपने केस के लिए पूरा कोड भी देखें ।


निष्पादक के साथ पूर्ण उदाहरण
Ermer Erden

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.