Movatterモバイル変換


[0]ホーム

URL:


Keyboard shortcuts

Press or to navigate between chapters

PressS or/ to search in the book

Press? to show this help

PressEsc to hide this help

The Rust Reference

    Expressions

    Syntax
    Expression
          ExpressionWithoutBlock
        |ExpressionWithBlock

    ExpressionWithoutBlock
        OuterAttribute*
        (
            LiteralExpression
          |PathExpression
          |OperatorExpression
          |GroupedExpression
          |ArrayExpression
          |AwaitExpression
          |IndexExpression
          |TupleExpression
          |TupleIndexingExpression
          |StructExpression
          |CallExpression
          |MethodCallExpression
          |FieldExpression
          |ClosureExpression
          |AsyncBlockExpression
          |ContinueExpression
          |BreakExpression
          |RangeExpression
          |ReturnExpression
          |UnderscoreExpression
          |MacroInvocation
        )

    ExpressionWithBlock
        OuterAttribute*
        (
            BlockExpression
          |ConstBlockExpression
          |UnsafeBlockExpression
          |LoopExpression
          |IfExpression
          |MatchExpression
        )

    An expression may have two roles: it always produces avalue, and it may haveeffects (otherwise known as “side effects”).

    An expressionevaluates to a value, and has effects duringevaluation.

    Many expressions contain sub-expressions, called theoperands of the expression.

    The meaning of each kind of expression dictates several things:

    • Whether or not to evaluate the operands when evaluating the expression
    • The order in which to evaluate the operands
    • How to combine the operands’ values to obtain the value of the expression

    In this way, the structure of expressions dictates the structure of execution.Blocks are just another kind of expression, so blocks, statements, expressions, and blocks again can recursively nest inside each other to an arbitrary depth.

    Note

    We give names to the operands of expressions so that we may discuss them, but these names are not stable and may be changed.

    Expression precedence

    The precedence of Rust operators and expressions is ordered as follows, going from strong to weak.Binary Operators at the same precedence level are grouped in the order given by their associativity.

    Operator/ExpressionAssociativity
    Paths
    Method calls
    Field expressionsleft to right
    Function calls,array indexing
    ?
    Unary-!*borrow
    asleft to right
    */%left to right
    +-left to right
    <<>>left to right
    &left to right
    ^left to right
    |left to right
    ==!=<><=>=Require parentheses
    &&left to right
    ||left to right
    ....=Require parentheses
    =+=-=*=/=%=
    &=|=^=<<=>>=
    right to left
    returnbreakclosures

    Evaluation order of operands

    The following list of expressions all evaluate their operands the same way, as described after the list.Other expressions either don’t take operands or evaluate them conditionally as described on their respective pages.

    • Dereference expression
    • Error propagation expression
    • Negation expression
    • Arithmetic and logical binary operators
    • Comparison operators
    • Type cast expression
    • Grouped expression
    • Array expression
    • Await expression
    • Index expression
    • Tuple expression
    • Tuple index expression
    • Struct expression
    • Call expression
    • Method call expression
    • Field expression
    • Break expression
    • Range expression
    • Return expression

    The operands of these expressions are evaluated prior to applying the effects of the expression.Expressions taking multiple operands are evaluated left to right as written in the source code.

    Note

    Which subexpressions are the operands of an expression is determined by expression precedence as per the previous section.

    For example, the twonext method calls will always be called in the same order:

    #![allow(unused)]fn main() {// Using vec instead of array to avoid references// since there is no stable owned array iterator// at the time this example was written.let mut one_two = vec![1, 2].into_iter();assert_eq!(    (1, 2),    (one_two.next().unwrap(), one_two.next().unwrap()));}

    Note

    Since this is applied recursively, these expressions are also evaluated from innermost to outermost, ignoring siblings until there are no inner subexpressions.

    Place Expressions and Value Expressions

    Expressions are divided into two main categories: place expressions and value expressions;there is also a third, minor category of expressions called assignee expressions.Within each expression, operands may likewise occur in either place context or value context.The evaluation of an expression depends both on its own category and the context it occurs within.

    Aplace expression is an expression that represents a memory location.

    These expressions arepaths which refer to local variables,static variables,dereferences (*expr),array indexing expressions (expr[expr]),field references (expr.f) and parenthesized place expressions.

    All other expressions are value expressions.

    Avalue expression is an expression that represents an actual value.

    The following contexts areplace expression contexts:

    Note

    Historically, place expressions were calledlvalues and value expressions were calledrvalues.

    Anassignee expression is an expression that appears in the left operand of anassignment expression.Explicitly, the assignee expressions are:

    Arbitrary parenthesisation is permitted inside assignee expressions.

    Moved and copied types

    When a place expression is evaluated in a value expression context, or is bound by value in a pattern, it denotes the value heldin that memory location.

    If the type of that value implementsCopy, then the value will be copied.

    In the remaining situations, if that type isSized, then it may be possible to move the value.

    Only the following place expressions may be moved out of:

    After moving out of a place expression that evaluates to a local variable, the location is deinitialized and cannot be read from again until it is reinitialized.

    In all other cases, trying to use a place expression in a value expression context is an error.

    Mutability

    For a place expression to beassigned to, mutablyborrowed,implicitly mutably borrowed, or bound to a pattern containingref mut, it must bemutable.We call thesemutable place expressions.In contrast, other place expressions are calledimmutable place expressions.

    The following expressions can be mutable place expression contexts:

    • Mutablevariables which are not currently borrowed.
    • Mutablestatic items.
    • Temporary values.
    • Fields: this evaluates the subexpression in a mutable place expression context.
    • Dereferences of a*mut T pointer.
    • Dereference of a variable, or field of a variable, with type&mut T.Note: This is an exception to the requirement of the next rule.
    • Dereferences of a type that implementsDerefMut:this then requires that the value being dereferenced is evaluated in a mutable place expression context.
    • Array indexing of a type that implementsIndexMut:this then evaluates the value being indexed, but not the index, in mutable place expression context.

    Temporaries

    When using a value expression in most place expression contexts, a temporary unnamed memory location is created and initialized to that value.The expression evaluates to that location instead, except ifpromoted to astatic.Thedrop scope of the temporary is usually the end of the enclosing statement.

    Implicit Borrows

    Certain expressions will treat an expression as a place expression by implicitly borrowing it.For example, it is possible to compare two unsizedslices for equality directly, because the== operator implicitly borrows its operands:

    #![allow(unused)]fn main() {let c = [1, 2, 3];let d = vec![1, 2, 3];let a: &[i32];let b: &[i32];a = &c;b = &d;// ...*a == *b;// Equivalent form:::std::cmp::PartialEq::eq(&*a, &*b);}

    Implicit borrows may be taken in the following expressions:

    Overloading Traits

    Many of the following operators and expressions can also be overloaded for other types using traits instd::ops orstd::cmp.These traits also exist incore::ops andcore::cmp with the same names.

    Expression Attributes

    Outer attributes before an expression are allowed only in a few specific cases:

    They are never allowed before:


    [8]ページ先頭

    ©2009-2025 Movatter.jp