Block expressions
Syntax
BlockExpression :
{
InnerAttribute*
Statement*
Expression?
}
A block expression is similar to a module in terms of the declarations that are possible, but can also contain statements and end with an expression. Each block conceptually introduces a new namespace scope. Use items can bring new names into scopes and declared items are in scope for only the block itself.
A block will execute each statement sequentially, and then execute the
expression, if given. If the block doesn't end in an expression, its value is
()
:
# #![allow(unused_variables)] #fn main() { let x: () = { println!("Hello."); }; #}
If it ends in an expression, its value and type are that of the expression:
# #![allow(unused_variables)] #fn main() { let x: i32 = { println!("Hello."); 5 }; assert_eq!(5, x); #}
Blocks are always value expressions and evaluate the last expression in value expression context. This can be used to force moving a value if really needed.
unsafe
blocks
Syntax
UnsafeBlockExpression :
unsafe
BlockExpression
See unsafe
block for more information on when to use unsafe
A block of code can be prefixed with the unsafe
keyword, to permit calling
unsafe
functions or dereferencing raw pointers within a safe function. Examples:
# #![allow(unused_variables)] #fn main() { unsafe { let b = [13u8, 17u8]; let a = &b[0] as *const u8; assert_eq!(*a, 13); assert_eq!(*a.offset(1), 17); } # unsafe fn f() -> i32 { 10 } let a = unsafe { f() }; #}
Attributes on block expressions
Block expressions allow outer attributes and inner attributes directly after
the opening brace when the block expression is the outer expression of an
expression statement or the final expression of another block expression. The
attributes that have meaning on a block expression are cfg
, and the lint
check attributes.
For example, this function returns true
on unix platforms and false
on other
platforms.
# #![allow(unused_variables)] #fn main() { fn is_unix_platform() -> bool { #[cfg(unix)] { true } #[cfg(not(unix))] { false } } #}