Rust - Итератор и закрытие
В этой главе мы узнаем, как работают итераторы и замыкания в RUST.
Итераторы
Итератор помогает перебирать набор значений, таких как массивы, векторы, карты и т. Д. Итераторы реализуют черту Iterator, которая определена в стандартной библиотеке Rust. Метод iter () возвращает объект-итератор коллекции. Значения в объекте итератора называются элементами. Метод next () итератора может использоваться для обхода элементов. Метод next () возвращает значение None, когда достигает конца коллекции.
В следующем примере итератор используется для чтения значений из массива.
fn main() {
//declare an array
let a = [10,20,30];
let mut iter = a.iter();
// fetch an iterator object for the array
println!("{:?}",iter);
//fetch individual values from the iterator object
println!("{:?}",iter.next());
println!("{:?}",iter.next());
println!("{:?}",iter.next());
println!("{:?}",iter.next());
}
Вывод
Iter([10, 20, 30])
Some(10)
Some(20)
Some(30)
None
Если коллекция, такая как array или Vector, реализует черту Iterator, то ее можно пройти, используя синтаксис for ... in, как показано ниже:
fn main() {
let a = [10,20,30];
let iter = a.iter();
for data in iter{
print!("{}\t",data);
}
}
Вывод
10 20 30
Следующие 3 метода возвращают объект-итератор из коллекции, где T представляет элементы в коллекции.
Старший Нет | Методы и описание |
---|---|
1 | iter() дает итератор над & T (ссылка на T) |
2 | into_iter() дает итератор по T |
3 | iter_mut() дает итератор над & mut T |
Иллюстрация: iter ()
Функция iter () использует концепцию заимствования. Он возвращает ссылку на каждый элемент коллекции, оставляя коллекцию нетронутой и доступной для повторного использования после цикла.
fn main() {
let names = vec!["Kannan", "Mohtashim", "Kiran"];
for name in names.iter() {
match name {
&"Mohtashim" => println!("There is a rustacean among us!"),
_ => println!("Hello {}", name),
}
}
println!("{:?}",names);
// reusing the collection after iteration
}
Вывод
Hello Kannan
There is a rustacean among us!
Hello Kiran
["Kannan", "Mohtashim", "Kiran"]
Иллюстрация - into_iter ()
Эта функция использует концепцию владения. Он перемещает значения из коллекции в объект iter, т. Е. Коллекция потребляется и больше не доступна для повторного использования.
fn main(){
let names = vec!["Kannan", "Mohtashim", "Kiran"];
for name in names.into_iter() {
match name {
"Mohtashim" => println!("There is a rustacean among us!"),
_ => println!("Hello {}", name),
}
}
// cannot reuse the collection after iteration
//println!("{:?}",names);
//Error:Cannot access after ownership move
}
Вывод
Hello Kannan
There is a rustacean among us!
Hello Kiran
Иллюстрация - for и iter_mut ()
Эта функция похожа на функцию iter () . Однако эта функция может изменять элементы в коллекции.
fn main() {
let mut names = vec!["Kannan", "Mohtashim", "Kiran"];
for name in names.iter_mut() {
match name {
&mut "Mohtashim" => println!("There is a rustacean among us!"),
_ => println!("Hello {}", name),
}
}
println!("{:?}",names);
//// reusing the collection after iteration
}
Вывод
Hello Kannan
There is a rustacean among us!
Hello Kiran
["Kannan", "Mohtashim", "Kiran"]
Закрытие
Замыкание относится к функции внутри другой функции. Это анонимные функции - функции без имени. Замыкание можно использовать для присвоения функции переменной. Это позволяет программе передавать функцию в качестве параметра другим функциям. Замыкание также известно как встроенная функция. Переменные во внешней функции могут быть доступны встроенным функциям.
Синтаксис: определение замыкания
Определение замыкания может дополнительно иметь параметры. Параметры заключены в две вертикальные полосы.
let closure_function = |parameter| {
//logic
}
Синтаксис вызова Closure реализует Fnчерты. Итак, его можно вызвать с помощью() синтаксис.
closure_function(parameter); //invoking
Иллюстрация
В следующем примере определяется замыкание is_even в функции main () . Замыкание возвращает истину, если число четное, и ложь, если число нечетное.
fn main(){
let is_even = |x| {
x%2==0
};
let no = 13;
println!("{} is even ? {}",no,is_even(no));
}
Вывод
13 is even ? false
Иллюстрация
fn main(){
let val = 10;
// declared outside
let closure2 = |x| {
x + val //inner function accessing outer fn variable
};
println!("{}",closure2(2));
}
Функция main () объявляет переменную val и закрытие. Замыкание обращается к переменной, объявленной во внешней функции main () .
Вывод
12