XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Смотрите также:
std::iter::Iterator::any
Поиск через итераторы
Iterator::find - функция, которая проходит через итератор и ищет первое значение, удовлетворяющее условию. Если ни одно из значений не удовлетворяет условию, то возвращается None. Её сигнатура:
pub trait Iterator {
// Тип, по которому выполняется итерирование
type Item;
// `find` принимает `&mut self`, что означает заимствование и
// изменение, но не поглощение `self`.
fn find(&mut self, predicate: P) -> Option where
// `FnMut` означает, что любая захваченная переменная
// может быть изменена, но не поглощена. `&Self::Item`
// указывает на захват аргументов замыкания по ссылке.
P: FnMut(&Self::Item) -> bool {}
}
fn main() {
let vec1 = vec![1, 2, 3];
let vec2 = vec![4, 5, 6];
// `iter()` для векторов производит `&i32`.
let mut iter = vec1.iter();
// `into_iter()` для векторов производит `i32`.
let mut into_iter = vec2.into_iter();
// `iter()` производит `&i32` и мы хотим сослаться на одно из его значений,
// так что мы деструктурируем `&&i32` в `i32`
println!("Найдём 2 в vec1: {:?}", iter .find(|&&x| x == 2));
// `into_iter()` производит `i32` и мы хотим сослаться на одно из его значений
// так что мы деструктурируем `&i32` в `i32`
println!("Найдём 2 в vec2: {:?}", into_iter.find(| &x| x == 2));
let array1 = [1, 2, 3];
let array2 = [4, 5, 6];
// `iter()` для массивов производит `&i32`
println!("Найдём 2 в array1: {:?}", array1.iter() .find(|&&x| x == 2));
// `into_iter()` для массивов также производит `&i32`
println!("Найдём 2 в array2: {:?}", array2.into_iter().find(|&&x| x == 2));
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Iterator::find даёт ссылку на элемент. Но если вы хотите получить его индекс, используйте Iterator::position.
fn main() {
let vec = vec![1, 9, 3, 3, 13, 2];
let index_of_first_even_number = vec.iter().position(|x| x % 2 == 0);
assert_eq!(index_of_first_even_number, Some(5));
let index_of_first_negative_number = vec.iter().position(|x| x <&0);
assert_eq!(index_of_first_negative_number, None);
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Смотрите также:
std::iter::Iterator::find
std::iter::Iterator::find_map
std::iter::Iterator::position
std::iter::Iterator::rposition
Функции высшего порядка
Rust предоставляет Функции Высшего Порядка (ФВП). Это функции, которые получают на вход одну или больше функций и производят более полезные функции. ФВП и ленивые итераторы дают языку Rust функциональный вид.
fn is_odd(n: u32) -> bool {
n % 2 == 1
}
fn main() {
println!("Найти сумму всех квадратов нечётных чисел не больше 1000");
let upper = 1000;
// Императивный подход
// Объявляем переменную-накопитель
let mut acc = 0;
// Итерировать: 0, 1, 2, ... до бесконечности
for n in 0.. {
// Квадрат числа
let n_squared = n * n;
if n_squared >= upper {
// Остановить цикл, если превысили верхний лимит
break;
} else if is_odd(n_squared) {
// Складывать число, если оно нечётное
acc += n_squared;
}
}
println!("императивный стиль: {}", acc);
// Функциональный подход
let sum_of_squared_odd_numbers: u32 =
(0..).map(|n| n * n) // Все натуральные числа возводим в квадрат
.take_while(|&n| n < upper) // Ниже верхнего предела
.filter(|n| is_odd(*n)) // Выбираем нечётные
.fold(0, |sum, i| sum + i); // Суммируем
println!("функциональный стиль: {}", sum_of_squared_odd_numbers);
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Option и Iterator реализуют свою часть функций высшего порядка..
Расходящиеся функции
Расходящиеся функции никогда не возвращают результат. Они помечены с помощью !, который является пустым типом.
#![allow(unused)]
fn main() {
fn foo() -> ! {
panic!("Этот вызов никогда не вернёт управление.");
}
}
В отличие от всех других типов, этот не может быть создан, потому что набор всех возможных значений этого типа пуст. Обратите внимание, что он отличается от типа (), который имеет ровно одно возможное значение.
Например, эта функция имеет возвращаемое значение, хотя о нём нет информации.
fn some_fn() {
()
}
fn main() {
let a: () = some_fn();
println!("Эта функция возвращает управление и вы можете увидеть эту строку.")
}
В отличие от этой функции, которая никогда не вернёт элемент управления вызывающей стороне.