macro_rules! select {
( ) => { ... };
(
@ codegen futs $ fut : tt default $ default : tt complete ( ) ) => { ... };
( @ codegen futs $ fut : tt default ( ) complete $ complete : tt ) => { ... };
(
@ codegen futs (
$ ( $ fut_pat : pat = $ fut_name : ident => $ fut_body : expr , ) * ) default
( $ default : expr ) $ ( no_default $ no_default : ident ) * complete (
$ complete : expr ) ) => { ... };
(
@ parse_list cases ( $ ( $ head : tt ) * ) tokens ( ) labels $ labels : tt ) => { ... };
( @ parse_list cases $ cases : tt tokens $ tokens : tt labels ( ) ) => { ... };
(
@ parse_list cases ( $ ( $ head : tt ) * ) tokens (
default => $ ( $ tail : tt ) * ) labels $ labels : tt ) => { ... };
(
@ parse_list cases ( $ ( $ head : tt ) * ) tokens (
complete => $ ( $ tail : tt ) * ) labels $ labels : tt ) => { ... };
(
@ parse_list cases ( $ ( $ head : tt ) * ) tokens (
$ fut_pat : pat = $ fut_ident : ident => $ ( $ tail : tt ) * ) labels $ labels
: tt ) => { ... };
(
@ parse_list cases ( $ ( $ head : tt ) * ) tokens (
$ fut_pat : pat = $ fut_expr : expr => $ ( $ tail : tt ) * ) labels (
$ label : tt $ ( $ labels : tt ) * ) ) => { ... };
(
@ parse_list cases ( $ ( $ head : tt ) * ) tokens (
$ kind : ident $ fut_pat : pat = $ fut_ident : ident => $ body : expr , $ (
$ tail : tt ) * ) labels $ labels : tt ) => { ... };
(
@ parse_list cases ( $ ( $ head : tt ) * ) tokens (
$ kind : ident $ fut_pat : pat = $ fut_ident : ident => $ body : expr ; $ (
$ tail : tt ) * ) labels $ labels : tt ) => { ... };
(
@ parse_list cases ( $ ( $ head : tt ) * ) tokens (
$ kind : ident $ fut_pat : pat = $ fut_ident : ident => $ body : block $ (
$ tail : tt ) * ) labels $ labels : tt ) => { ... };
(
@ parse_list cases ( $ ( $ head : tt ) * ) tokens (
$ kind : ident $ fut_pat : pat = $ fut_ident : ident => $ body : expr ) labels
$ labels : tt ) => { ... };
(
@ parse_list cases ( $ ( $ head : tt ) * ) tokens ( $ ( tail : tt ) * ) labels
$ labels : tt ) => { ... };
(
@ parse_list_error1 default $ ( $ tail : tt ) * ) => { ... };
(
@ parse_list_error1 complete $ ( $ tail : tt ) * ) => { ... };
(
@ parse_list_error1 $ fut_pat : pat = $ fut_expr : ident $ ( $ tail : tt ) * ) => { ... };
(
@ parse_list_error1 __DEFAULT _ = __DEFAULT_IDENT $ ( $ tail : tt ) * ) => { ... };
(
@ parse_list_error1 __COMPLETE _ = __COMPLETE_IDENT $ ( $ tail : tt ) * ) => { ... };
(
@ parse_list error1 __FUTURE $ fut_pat : pat = $ fut_ident : ident $ (
$ tail : tt ) * ) => { ... };
(
@ parse_list_error1 $ t : tt $ ( $ tail : tt ) * ) => { ... };
(
@ parse_list_error_2 => $ body : expr ; $ ( $ tail : tt ) * ) => { ... };
( @ parse_list_error_2 => $ ( $ tail : tt ) * ) => { ... };
(
@ parse_list_error_2 $ ( $ tail : tt ) * ) => { ... };
(
@ parse_list_error2 $ ( $ tail : tt ) * ) => { ... };
(
@ parse_case futs $ fut : tt default $ default : tt complete $ complete : tt
cases ( ) ) => { ... };
(
@ parse_case futs $ fut : tt default ( ) complete $ complete : tt cases (
__DEFAULT $ pat : pat = __DEFAULT_IDENT => $ body : tt , $ ( $ tail : tt ) * )
) => { ... };
(
@ parse_case futs $ fut : tt default $ default : tt complete $ complete : tt
cases (
__DEFAULT $ pat : pat = __DEFAULT_IDENT => $ body : tt , $ ( $ tail : tt ) * )
) => { ... };
(
@ parse_case futs $ fut : tt default $ default : tt complete ( ) cases (
__COMPLETE $ pat : pat = __COMPLETE_IDENT => $ body : tt , $ ( $ tail : tt ) *
) ) => { ... };
(
@ parse_case futs $ fut : tt default $ default : tt complete $ complete : tt
cases (
__COMPLETE $ pat : pat = __COMPLETE_IDENT => $ body : tt , $ ( $ tail : tt ) *
) ) => { ... };
(
@ parse_case futs ( $ ( $ futs : tt ) * ) default $ default : tt complete $
complete : tt cases (
__FUTURE $ pat : pat = $ ident : ident => $ body : tt , $ ( $ tail : tt ) * )
) => { ... };
(
@ parse_case futs $ fut : tt default $ default : tt complete $ complete : tt
cases ( $ case : ident $ args : tt => $ body : tt , $ ( $ tail : tt ) * ) ) => { ... };
(
@ $ ( $ tokens : tt ) * ) => { ... };
( $ ( $ tokens : tt ) * ) => { ... };
}
Polls multiple futures and streams simultaneously, executing the branch
for the future that finishes first. Futures passed to
select!
must be Unpin
and implement FusedFuture
.
Futures and streams which are not already fused can be fused using the
.fuse()
method. Note, though, that fusing a future or stream directly
in the call to select!
will not be enough to prevent it from being
polled after completion if the select!
call is in a loop, so when
select!
ing in a loop, users should take care to fuse()
outside of
the loop.
select!
can select over futures with different output types, but each
branch has to have the same return type.
This macro is only usable inside of async functions, closures, and blocks.
#![feature(pin, async_await, await_macro, futures_api)]
use futures::future::{self, FutureExt};
use futures::select;
let mut a = future::ready(4);
let mut b = future::empty::<()>();
let res = select! {
a_res = a => a_res + 1,
_ = b => 0,
};
assert_eq!(res, 5);
#![feature(pin, async_await, await_macro, futures_api)]
use futures::future::{self, FutureExt};
use futures::stream::{self, StreamExt};
use futures::select;
let mut st = stream::iter(vec![2]).fuse();
let mut fut = future::empty::<()>();
select! {
x = st.next() => assert_eq!(Some(2), x),
_ = fut => panic!(),
};
select
also accepts a complete
branch and a default
branch.
complete
will run if all futures and streams have already been
exhausted. default
will run if no futures or streams are
immediately ready. complete
takes priority over default
in
the case where all futures have completed.
#![feature(pin, async_await, await_macro, futures_api)]
use futures::future::{self, FutureExt};
use futures::select;
let mut a_fut = future::ready(4);
let mut b_fut = future::ready(6);
let mut total = 0;
loop {
select! {
a = a_fut => total += a,
b = b_fut => total += b,
complete => break,
default => panic!(),
};
}
assert_eq!(total, 10);
Note that the futures that have been matched over can still be mutated
from inside the select!
block's branches. This can be used to implement
more complex behavior such as timer resets or writing into the head of
a stream.