亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

我如何有條件地退回不同類型的期貨?

我如何有條件地退回不同類型的期貨?

牧羊人nacy 2020-02-01 17:09:36
我有一個方法,根據謂詞的不同,它會返回一個將來或另一個。換句話說,一個if-else表達式返回一個future:extern crate futures; // 0.1.23use futures::{future, Future};fn f() -> impl Future<Item = usize, Error = ()> {    if 1 > 0 {        future::ok(2).map(|x| x)    } else {        future::ok(10).and_then(|x| future::ok(x + 2))    }}這不會編譯:error[E0308]: if and else have incompatible types  --> src/lib.rs:6:5   |6  | /     if 1 > 0 {7  | |         future::ok(2).map(|x| x)8  | |     } else {9  | |         future::ok(10).and_then(|x| future::ok(x + 2))10 | |     }   | |_____^ expected struct `futures::Map`, found struct `futures::AndThen`   |   = note: expected type `futures::Map<futures::FutureResult<{integer}, _>, [closure@src/lib.rs:7:27: 7:32]>`              found type `futures::AndThen<futures::FutureResult<{integer}, _>, futures::FutureResult<{integer}, _>, [closure@src/lib.rs:9:33: 9:54]>`期貨的創建方式不同,可能包含閉包,因此它們的類型不相等。理想情況下,該解決方案不使用Boxes,因為我的異步邏輯的其余部分都不使用它們。期貨中的if-else邏輯通常如何完成?
查看完整描述

1 回答

?
藍山帝景

TA貢獻1843條經驗 獲得超7個贊

Either

使用futures::future::Either沒有額外的堆分配:


extern crate futures; // 0.1.23


use futures::{

    future::{self, Either},

    Future,

};


fn f() -> impl Future<Item = usize, Error = ()> {

    if 1 > 0 {

        Either::A(future::ok(2).map(|x| x))

    } else {

        Either::B(future::ok(10).and_then(|x| future::ok(x + 2)))

    }

}

但是,這需要固定的堆棧分配。如果A占用1個字節并在99%的時間內發生,但B占用512個字節,則您Either將始終占用512個字節(加上一些字節)。這并不總是勝利。


裝箱特征對象

extern crate futures; // 0.1.23


use futures::{future, Future};


fn f() -> Box<Future<Item = usize, Error = ()>> {

    if 1 > 0 {

        Box::new(future::ok(2).map(|x| x))

    } else {

        Box::new(future::ok(10).and_then(|x| future::ok(x + 2)))

    }

}

正如Matthieu M.指出的那樣,可以將兩種解決方案結合起來:


我會注意到對于大的情況有一個中間的解決方案B:Either(A, Box<B>)。這樣,您僅需在極少數情況下為堆分配付費B


請注意,Either如果您有兩個以上的條件(Either<A, Either<B, C>>; Either<Either<A, B>, Either<C, D>>等),也可以堆疊s :


fn f(v: i32) -> impl Future<Item = i32, Error = ()> {

    use std::cmp::Ordering;

    match v.cmp(&0) {

        Ordering::Less => Either::A(future::ok(2).map(|x| -x)),

        Ordering::Equal => Either::B(Either::A(future::ok(0))),

        Ordering::Greater => Either::B(Either::B(future::ok(-2).map(|x| x * x))),

    }

}


查看完整回答
反對 回復 2020-02-01
  • 1 回答
  • 0 關注
  • 436 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號