std::ops

Module std::ops

Overloadable operators.

Implementing these traits allows you to overload certain operators.

Some of these traits are imported by the prelude, so they are available in every Rust program. Only operators backed by traits can be overloaded. For example, the addition operator (+) can be overloaded through the Add trait, but since the assignment operator (=) has no backing trait, there is no way of overloading its semantics. Additionally, this module does not provide any mechanism to create new operators. If traitless overloading or custom operators are required, you should look toward macros or compiler plugins to extend Rust's syntax.

Note that the && and || operators short-circuit, i.e. they only evaluate their second operand if it contributes to the result. Since this behavior is not enforceable by traits, && and || are not supported as overloadable operators.

Many of the operators take their operands by value. In non-generic contexts involving built-in types, this is usually not a problem. However, using these operators in generic code, requires some attention if values have to be reused as opposed to letting the operators consume them. One option is to occasionally use clone. Another option is to rely on the types involved providing additional operator implementations for references. For example, for a user-defined type T which is supposed to support addition, it is probably a good idea to have both T and &T implement the traits Add<T> and Add<&T> so that generic code can be written without unnecessary cloning.

Examples

This example creates a Point struct that implements Add and Sub, and then demonstrates adding and subtracting two Points.

use std::ops::{Add, Sub};

#[derive(Debug)]
struct Point {
    x: i32,
    y: i32,
}

impl Add for Point {
    type Output = Point;

    fn add(self, other: Point) -> Point {
        Point {x: self.x + other.x, y: self.y + other.y}
    }
}

impl Sub for Point {
    type Output = Point;

    fn sub(self, other: Point) -> Point {
        Point {x: self.x - other.x, y: self.y - other.y}
    }
}
fn main() {
    println!("{:?}", Point {x: 1, y: 0} + Point {x: 2, y: 3});
    println!("{:?}", Point {x: 1, y: 0} - Point {x: 2, y: 3});
}

See the documentation for each trait for an example implementation.

The Fn, FnMut, and FnOnce traits are implemented by types that can be invoked like functions. Note that Fn takes &self, FnMut takes &mut self and FnOnce takes self. These correspond to the three kinds of methods that can be invoked on an instance: call-by-reference, call-by-mutable-reference, and call-by-value. The most common use of these traits is to act as bounds to higher-level functions that take functions or closures as arguments.

Taking a Fn as a parameter:

fn call_with_one<F>(func: F) -> usize
    where F: Fn(usize) -> usize
{
    func(1)
}

let double = |x| x * 2;
assert_eq!(call_with_one(double), 2);

Taking a FnMut as a parameter:

fn do_twice<F>(mut func: F)
    where F: FnMut()
{
    func();
    func();
}

let mut x: usize = 1;
{
    let add_two_to_x = || x += 2;
    do_twice(add_two_to_x);
}

assert_eq!(x, 5);

Taking a FnOnce as a parameter:

fn consume_with_relish<F>(func: F)
    where F: FnOnce() -> String
{
    // `func` consumes its captured variables, so it cannot be run more
    // than once
    println!("Consumed: {}", func());

    println!("Delicious!");

    // Attempting to invoke `func()` again will throw a `use of moved
    // value` error for `func`
}

let x = String::from("x");
let consume_and_return_x = move || x;
consume_with_relish(consume_and_return_x);

// `consume_and_return_x` can no longer be invoked at this point

Structs

Range

A (half-open) range which is bounded at both ends: { x | start <= x < end }. Use start..end (two dots) for its shorthand.

RangeFrom

A range which is only bounded below: { x | start <= x }. Use start.. for its shorthand.

RangeFull

An unbounded range. Use .. (two dots) for its shorthand.

RangeTo

A range which is only bounded above: { x | x < end }. Use ..end (two dots) for its shorthand.

RangeToInclusive [
Experimental
]

An inclusive range which is only bounded above: { x | x <= end }. Use ...end (three dots) for its shorthand.

Enums

RangeInclusive [
Experimental
]

An inclusive range which is bounded at both ends: { x | start <= x <= end }. Use start...end (three dots) for its shorthand.

Traits

Add

The addition operator +.

AddAssign

The addition assignment operator +=.

BitAnd

The bitwise AND operator &.

BitAndAssign

The bitwise AND assignment operator &=.

BitOr

The bitwise OR operator |.

BitOrAssign

The bitwise OR assignment operator |=.

BitXor

The bitwise XOR operator ^.

BitXorAssign

The bitwise XOR assignment operator ^=.

Deref

The Deref trait is used to specify the functionality of dereferencing operations, like *v.

DerefMut

The DerefMut trait is used to specify the functionality of dereferencing mutably like *v = 1;

Div

The division operator /.

DivAssign

The division assignment operator /=.

Drop

The Drop trait is used to run some code when a value goes out of scope. This is sometimes called a 'destructor'.

Fn

A version of the call operator that takes an immutable receiver.

FnMut

A version of the call operator that takes a mutable receiver.

FnOnce

A version of the call operator that takes a by-value receiver.

Index

The Index trait is used to specify the functionality of indexing operations like container[index] when used in an immutable context.

IndexMut

The IndexMut trait is used to specify the functionality of indexing operations like container[index] when used in a mutable context.

Mul

The multiplication operator *.

MulAssign

The multiplication assignment operator *=.

Neg

The unary negation operator -.

Not

The unary logical negation operator !.

Rem

The remainder operator %.

RemAssign

The remainder assignment operator %=.

Shl

The left shift operator <<.

ShlAssign

The left shift assignment operator <<=.

Shr

The right shift operator >>.

ShrAssign

The right shift assignment operator >>=.

Sub

The subtraction operator -.

SubAssign

The subtraction assignment operator -=.

BoxPlace [
Experimental
]

Specialization of Place trait supporting box EXPR.

Boxed [
Experimental
]

Core trait for the box EXPR form.

Carrier [
Experimental
]

A trait for types which have success and error states and are meant to work with the question mark operator. When the ? operator is used with a value, whether the value is in the success or error state is determined by calling translate.

CoerceUnsized [
Experimental
]

Trait that indicates that this is a pointer or a wrapper for one, where unsizing can be performed on the pointee.

InPlace [
Experimental
]

Specialization of Place trait supporting PLACE <- EXPR.

Place [
Experimental
]

Both PLACE <- EXPR and box EXPR desugar into expressions that allocate an intermediate "place" that holds uninitialized state. The desugaring evaluates EXPR, and writes the result at the address returned by the pointer method of this trait.

Placer [
Experimental
]

Interface to implementations of PLACE <- EXPR.

© 2010 The Rust Project Developers
Licensed under the Apache License, Version 2.0 or the MIT license, at your option.
https://doc.rust-lang.org/std/ops/index.html

在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号

意见反馈
返回顶部