Skip to content

slice::contains

slice methods · Collections

Level: reference · for working programmers

One line: Is this value in the slice? A linear scan by ==.

pub fn contains(&self, x: &T) -> bool
where
    T: PartialEq,

Stable since 1.0.0.

It walks the slice from the front and compares with ==, so it is O(n) and needs only PartialEq. The argument is a reference even when T is Copy: nums.contains(&2), not nums.contains(2).

The Vec<String> trap. names.contains("Ann") is `error[E0308]: expected&String, found&str``. The signature wants&T,TisString, and a literal is a&str— two types that compare equal through==but are not the same type.names.contains(&"Ann".to_string())compiles, at the cost of an allocation just to ask a question;names.iter().any(|n| n == "Ann")asks it for free, becauseString == stris implemented. A slice of&strhas no such problem:tags.contains(&"green")`.

For many lookups against the same slice, a linear scan each time is the wrong tool — sort once and binary_search, or build a HashSet.

Example

slice_contains.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.

fn main() {
    let nums = [1, 2, 3];
    println!("{} {}", nums.contains(&2), nums.contains(&7));

    // It takes a reference even for a Copy type, so the argument is &2, not 2.
    let wanted = 3;
    println!("{}", nums.contains(&wanted));

    // The Vec<String> trap: contains wants a &String, and a literal is a &str.
    let names = vec![String::from("Ann"), String::from("Bob")];
    // names.contains("Ann");                     // error[E0308]: expected `&String`, found `&str`
    println!("{}", names.contains(&"Ann".to_string()));   // allocates just to ask
    println!("{}", names.iter().any(|n| n == "Ann"));    // no allocation

    // A slice of &str compares with a literal directly.
    let tags = ["red", "green"];
    println!("{}", tags.contains(&"green"));

    // Linear: it looks at every element until it finds one.
    let big: Vec<u32> = (0..1_000).collect();
    println!("{}", big.contains(&999));
}

Verified output of slice_contains.rs — regenerated by tools/run_examples.py, never hand-typed.

true false
true
true
true
true
true

See also

slice::contains in the standard library ↗