Разница copied и cloned
Методы copied и cloned решают похожую задачу: они превращают итератор, который выдаёт ссылки, в итератор, который выдаёт значения. Разница в том, что copied требует, чтобы тип реализовывал трейт Copy, и просто копирует значение побитово. Метод cloned требует трейт Clone и вызывает у элемента метод clone. Параметров оба метода не принимают и возвращают адаптер итератора.
Синтаксис
iter.copied()
iter.cloned()
Пример
Давайте посмотрим, как copied работает с итератором по ссылкам на числа:
fn main()
{
let nums = vec![1, 2, 3, 4, 5];
let res: Vec<i32> = nums.iter().copied().collect();
println!("{:?}", res);
}
Результат выполнения кода:
[1, 2, 3, 4, 5]
Пример
Давайте посмотрим, как cloned работает с итератором по ссылкам на строки:
fn main()
{
let strings = vec!["abcde".to_string(), "12345".to_string()];
let res: Vec<String> = strings.iter().cloned().collect();
println!("{:?}", res);
}
Результат выполнения кода:
["abcde", "12345"]
Пример
Давайте проверим, что copied не скомпилируется для типа, который не реализует Copy:
fn main()
{
let strings = vec!["abcde".to_string(), "12345".to_string()];
let res: Vec<String> = strings.iter().copied().collect();
println!("{:?}", res);
}
Компилятор выдаст ошибку, потому что String не реализует трейт Copy. В такой ситуации нужно использовать cloned.
Пример
Давайте сравним поведение обоих методов на одном и том же векторе чисел:
fn main()
{
let nums = vec![1, 2, 3, 4, 5];
let res1: Vec<i32> = nums.iter().copied().collect();
let res2: Vec<i32> = nums.iter().cloned().collect();
println!("{:?}", res1);
println!("{:?}", res2);
}
Результат выполнения кода:
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
Смотрите также
-
метод
copied,
который преобразует итератор по ссылкам в итератор по копиям значений -
метод
cloned,
который преобразует итератор по ссылкам в итератор по клонам значений -
метод
map,
который преобразует каждый элемент итератора с помощью функции -
трейт
Iterator,
который описывает базовое поведение всех итераторов