Почему std :: ve c :: Ve c реализует два типа признака Extend? - PullRequest
1 голос
/ 06 февраля 2020

Структура std::vec::Vec реализует два вида расширения, как указано здесь - impl<'a, T> Extend<&'a T> for Vec<T> и impl<T> Extend<T> for Vec<T>. В документации говорится, что первый тип - это «Расширяемая реализация, которая копирует элементы из ссылок, прежде чем помещать их в Ve c». Я довольно новичок в Rust, и я не уверен, правильно ли я понимаю.

Я бы предположил, что первый тип используется с эквивалентом нормальных итераторов C ++, а второй - используется с эквивалентом итераторов перемещения C ++.

Я пытаюсь написать функцию, которая принимает любую структуру данных, которая позволит вставлять i32 s в конец, поэтому я беру параметр, который реализует оба вида Extend, но я не могу понять, как задать параметры generi c, чтобы заставить его работать:

fn main() {
    let mut vec = std::vec::Vec::<i32>::new();
    add_stuff(&mut vec);
}

fn add_stuff<'a, Rec: std::iter::Extend<i32> + std::iter::Extend<&'a i32>>(receiver: &mut Rec) {
    let x = 1 + 4;
    receiver.extend(&[x]);
}

Компилятор жалуется, что &[x] "создает временный объект, который освобождается, пока все еще используется », что имеет смысл, потому что 'a приходит извне функции add_stuff. Но, конечно, я хочу, чтобы receiver.extend(&[x]) скопировал элемент из фрагмента временного массива и добавил его в конец контейнера, чтобы временный массив больше не использовался после возврата receiver.extend. Как правильно express что я хочу?

1 Ответ

2 голосов
/ 06 февраля 2020

С внешней стороны add_stuff, Rect должно быть расширено с помощью ссылки, срок жизни которой указан внутри add_stuff. Таким образом, вы можете потребовать, чтобы Rec можно было расширять ссылками на любое время жизни, используя более высокие оценки черт:

fn main() {
    let mut vec = std::vec::Vec::<i32>::new();
    add_stuff(&mut vec);
}

fn add_stuff<Rec>(receiver: &mut Rec)
    where
        for<'a> Rec: std::iter::Extend<&'a i32>
{
    let x = 1 + 4;
    receiver.extend(&[x]);
}

Более того, как вы видите, границы черт были слишком узкими. Одного из них должно быть достаточно, если вы последовательно используете receiver в пределах add_stuff.

Тем не менее, мне просто потребуется Extend<i32> и убедитесь, что add_stuff выполняет правильные действия внутри (если возможно) :

fn add_stuff<Rec>(receiver: &mut Rec)
    where
        Rec: std::iter::Extend<i32>
{
    let x = 1 + 4;
    receiver.extend(std::iter::once(x));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...