Ответ 1
Есть способ, который выполняет именно это: Vec::extend_from_slice
Пример:
let s = [0u8, 1, 2];
let mut v = Vec::new();
v.extend_from_slice(&s);
У меня есть фрагмент &[u8]
, и я хотел бы добавить его к Vec<u8>
с минимальным копированием. Вот два подхода, которые я знаю:
let s = [0u8, 1u8, 2u8];
let mut v = Vec::new();
v.extend(s.iter().map(|&i| i));
v.extend(s.to_vec().into_iter()); // allocates an extra copy of the slice
Есть ли лучший способ сделать это в Rust stable? (rustc 1.0.0-beta.2
)
Есть способ, который выполняет именно это: Vec::extend_from_slice
Пример:
let s = [0u8, 1, 2];
let mut v = Vec::new();
v.extend_from_slice(&s);
v.extend(s.iter().cloned());
Это эквивалентно использованию .map(|&i| i)
и минимальному копированию.
Проблема в том, что вы абсолютно не можете избежать копирования в этом случае. Вы не можете просто перемещать значения, потому что срез не владеет его содержимым, поэтому он может принимать только копию.
Теперь, при этом, нужно рассмотреть две вещи:
Ржавчина имеет тенденцию к inline довольно агрессивно; в этом коде достаточно информации для компилятора, чтобы просто скопировать значения непосредственно в пункт назначения без какого-либо промежуточного шага.
Закрытие в Rust не похоже на закрытие на большинстве других языков: они не требуют выделения кучи и могут быть непосредственно встроены, что делает их не менее эффективными, чем жесткое кодирование поведения напрямую.
Имейте в виду, что вышеупомянутые два зависят от оптимизации: они, как правило, работают лучше, но не гарантируются.
Но, сказав, что... то, что вы на самом деле пытаетесь сделать здесь в этом конкретном примере, - это добавить массив, выделенный в стек, который у вас есть. Я не знаю ни одного библиотечного кода, который может фактически воспользоваться этим фактом (поддержка значений массива в настоящий момент довольно слаба в Rust), но теоретически вы могли бы эффективно создать эквивалент into_iter()
, используя небезопасный код... но я не рекомендую это, и это, вероятно, не стоит хлопот.
Я не могу говорить о полном влиянии на производительность, но v + &s
будет работать на бета-версии, что, я считаю, просто похоже на то, что каждое значение добавляется к исходному Vec.