Macro block2::global_block

source ·
macro_rules! global_block {
    (
        $(#[$m:meta])*
        $vis:vis static $name:ident = || $(-> $r:ty)? $body:block $(;)?
    ) => { ... };
    (
        $(#[$m:meta])*
        $vis:vis static $name:ident = |$($a:ident: $t:ty),* $(,)?| $(-> $r:ty)? $body:block $(;)?
    ) => { ... };
}
Expand description

Construct a static GlobalBlock.

The syntax is similar to a static closure (except that all types have to be specified). Note that the block cannot capture its environment, its parameter types must be EncodeArgument and the return type must be EncodeReturn.

§Examples

use block2::global_block;
global_block! {
    static MY_BLOCK = || -> i32 {
        42
    };
}
assert_eq!(MY_BLOCK.call(()), 42);
use block2::global_block;
global_block! {
    static ADDER_BLOCK = |x: i32, y: i32| -> i32 {
        x + y
    };
}
assert_eq!(ADDER_BLOCK.call((5, 7)), 12);

The following does not compile because Box is not EncodeReturn:

use block2::global_block;
global_block! {
    pub static BLOCK = |b: Box<i32>| {};
}

This also doesn’t work (yet), as blocks are overly restrictive about the lifetimes involved.

use block2::global_block;
global_block! {
    pub static BLOCK_WITH_LIFETIME = |x: &i32| -> i32 {
        *x + 42
    };
}
let x = 5;
let res = BLOCK_WITH_LIFETIME.call((&x,));
assert_eq!(res, 47);

There is also no way to get a block function that’s generic over its parameters. One could imagine the following syntax would work, but it can’t due to implementation limitations:

use block2::global_block;
global_block! {
    pub static BLOCK<T: Encode> = |b: T| {};
}