https://doc.rust-lang.org/stable/reference/keywords.html
Original thread: https://twitter.com/jonhoo/status/1539661689880137728
as
: x as T
can do lossy conversion, so prefer T::try_from(x).expect("…")
if you want it to fail loudly (e.g., if a u64 doesn't fit in a u32).
https://rust-lang.github.io/rust-clippy/master/index.html#as_conversions
async
: in async
blocks, return
and ?
only bubble to the result of the future, whereas break
and continue
would affect the outer context and so re disallowed.
https://doc.rust-lang.org/stable/reference/expressions/block-expr.html#control-flow-operators
await
: await
is nothing but syntactic sugar for a loop
that calls Future::poll
and calls yield
on Poll::Pending
.
break
: You can pass a value to break in a loop
to make the loop
evaluate to that value.
https://doc.rust-lang.org/stable/reference/expressions/loop-expr.html#break-and-loop-values
const
: There are a lot more constifications planned, including allowing async {}
in const fn
!
continue
: continue
effectively evaluates to !
, which allows it to masquerade as any type.
crate
: These days, the two primary uses of crate
as a standalone keyword have mostly gone away: extern crate
is rarely used, and crate
as a visibility modifer won't happen (just use pub(crate)
instead).
dyn
: dyn
trait objects come with a default lifetime bound inherited from the containing wide pointer type.
https://doc.rust-lang.org/stable/reference/lifetime-elision.html#default-trait-object-lifetimes
else
: else
is about to get another meaning with let-else expressions, which are like .unwrap_or
for pattern matches!
enum
: For data-less enums ("C-style enums"), you can assign a value to only a subset of the variants, and the remaining ones get inferred automatically.
extern
: extern
on its own is an alias for extern "C"
— the two are interchangeable.
https://doc.rust-lang.org/stable/reference/items/external-blocks.html#abi
false
: false < true
.
https://doc.rust-lang.org/stable/reference/types/boolean.html#comparisons
fn
: You can write #![attr]
immediately inside a function to add attributes to the function itself (though it's not very idiomatic).
https://doc.rust-lang.org/stable/reference/items/functions.html#attributes-on-functions
for
: for
loops are really just syntax sugar for a loop
that calls IntoIterator::into_iter
and then matches on Iterator::next
.
if
: 🤔🤷
undefined
impl
: You can put const
s directly in impl
blocks to make "associated constants" for a type.
https://doc.rust-lang.org/stable/reference/items/associated-items.html#associated-constants
in
: Not specifically about in
, but any ..
expression is actually just a convenient constructor for a Range
type.
https://doc.rust-lang.org/stable/reference/expressions/range-expr.html
let
: The interaction between let _
and dropping are subtle and interesting.
loop
: There used to be a mode in the Rust compiler that turned every function body into loop {}
, which was used (among other things) to make rustdoc
faster. It was called "everybody loops" 😆.
match
: The expression that a match matches on is called a "scrutinee".
https://doc.rust-lang.org/stable/reference/glossary.html#scrutinee
mod
: You can make mod
load files from non-standard locations using the #[path]
attribute. Though use it sparingly, as it can be very confusing for other developers trying to sort through your code base.
https://doc.rust-lang.org/stable/reference/items/modules.html#the-path-attribute
move
: The "opposite" capture behavior of move
(that is, if move
isn't passed), is far from straightforward.
https://doc.rust-lang.org/stable/reference/types/closure.html#capture-modes
mut
: While mut
is techically short for "mutable", you're generally better off thinking about it as "MUTually exclusive".
https://docs.rs/dtolnay/latest/dtolnay/macro._02__reference_types.html
pub
: There are a lot of visibility modifiers between non-pub
and pub
. pub(crate)
and pub(super)
are both useful, but you can even specify pub(in crate::some_mod)
to get really specific.
https://doc.rust-lang.org/stable/reference/visibility-and-privacy.html
ref
: You can use ref
to match something as a reference in a pattern, instead of capturing it as a value. That's not a secret of ref
, it's just what it means, but it's so commonly confused that it's worth repeating.
https://doc.rust-lang.org/stable/reference/patterns.html#identifier-patterns
return
: return
has a secret, long-unimplemented sibling, become
, which is intended to one day maybe be used for functions that require guaranteed tail-call optimization.
https://rust-lang.github.io/rfcs/0601-replace-be-with-become.html
self
: self
is special when it comes to automatic inference of the lifetime of return values. Specifically, the lifetime of a &self
or &mut self
argument will always be inferred to be the lifetime of the return value (if lifetimes are elided).
https://doc.rust-lang.org/stable/reference/lifetime-elision.html
Self
:
undefined
static
: You can declare static
items inside function bodies to get a static
that only that function has access to (unless it gives out references). This can be handy for implementing singleton-like patterns.
https://doc.rust-lang.org/stable/reference/items/static-items.html#statics--generics
struct
: A tuple-like struct implicitly defines a free-standing function by the same name that acts as the type's constructor. And a unit-like struct implicitly defines a constant by that name!
https://doc.rust-lang.org/stable/reference/items/structs.html
super
: super
is only permitted to follow either another super
or an initial self
in paths, and if it follows a self
then the self
is effectively ignored.
trait
: Traits can have associated constants, both with and without default values.
https://doc.rust-lang.org/stable/reference/items/traits.html
true
: Even though bools in Rust are generally u8
s internally, it is illegal for true
to be represented by anything but 0x01
. This is to enable optimizations that use other bitpatterns to compress state (like Option::None == 0x02).
type
: You cannot construct a type through its type alias name.
https://doc.rust-lang.org/stable/reference/items/type-aliases.html
unsafe
: You don't currently have to use unsafe {}
to perform unsafe operations inside an unsafe fn
, though that's likely to get a lint in the future to encourage fine-grained safety tracking (and thinking).
use
: You can use the syntax use path::to::Trait as _
to bring a trait into scope (so you can call its methods) without also bringing the name into scope. Handy in cases where two traits have the same name for example.
https://doc.rust-lang.org/stable/reference/items/use-declarations.html#underscore-imports
where
: where
clauses do not need to reference the generic type parameters of the thing they're attached to. You can write, for example: where String: Clone
if you want to.
https://doc.rust-lang.org/stable/reference/items/generics.html#where-clauses
while
: While loops are particularly handy for cases where the iterator type is useful beyond iteration. For example, if you're iterating over a Path
(with Path::iter
), you can call .as_path()
on the iterator to get the remaining Path
.