#string #rust #hashset #ownership
#строка #Ржавчина #hashset #владение
Вопрос:
Когда я пытаюсь расширить a HashSet<String>
с помощью другого HashSet<String>
:
use std::collections::HashSet;
let mut a = HashSet::new();
a.insert("foo".to_owned());
let mut b = HashSet::new();
b.insert("bar".to_owned());
let c = a.extend(amp;b);
Я получаю:
error[E0271]: type mismatch resolving `<amp;HashSet<String> as IntoIterator>::Item == String`
--> src/main.rs:7:11
|
7 | let c = a.extend(amp;b);
| ^^^^^^ expected reference, found struct `String`
|
= note: expected reference `amp;String`
found struct `String`
Как мне это сделать?
Комментарии:
1. Принятый ответ на другой вопрос не касается того, что задано здесь, потому что он рекомендует
a.extend(amp;b)
, какой сбой для операции. Это работает в другом ответе, потому что в другом ответе используются элементы set, которыеCopy
. (Я был немного удивлен, чтоa.extend(amp;b) works for
элементы Copy`, интересно, какой механизм это позволяет.)
Ответ №1:
HashSet::extend()
исходит из Extend
признака и, следовательно, принимает любой итератор (или итерируемый), а не только набор.
Если вы передаете ему ссылку на набор, эта ссылка является итеративной, но итератор создает ссылки на элементы набора — в данном случае amp;String
. Поскольку HashSet::<String>::extend()
ожидается, что итератор, который создает фактические строки, не компилируется. Есть два способа устранить проблему:
- передавая set
b
extend
по значению:a.extend(b)
; - путем создания явного итератора из
b
использованияb.iter()
и клонирования создаваемых им значений :a.extend(b.iter().cloned())
.
В первом варианте b
он будет использоваться и, следовательно, больше не будет использоваться вызывающей стороной, но строки из него будут использоваться повторно a
. Во втором варианте b
он останется пригодным для использования, но его строки будут скопированы для хранения a
.
Обратите внимание, что ни в одном из вариантов не имеет смысла фиксировать возвращаемое значение extend()
, поскольку оно работает побочным эффектом и не возвращает полезное значение.