Вы не можете использовать сопоставление шаблонов с образцами срезов в этом сценарии.
Как вы правильно отметили при редактировании вашего вопроса, перемещение значения из Vec
оставляет его с неинициализированной памятью. Это может затем вызвать Undefined Behavior, когда Vec
впоследствии будет удален, потому что его реализация Drop
должна освободить память кучи и, возможно, удалить каждый элемент.
В настоящее время нет способа express, который ваш параметр типа F
не имеет реализации Drop
или что его можно безопасно вызвать из неинициализированной памяти.
Вы в значительной степени должны забыть об использовании шаблона среза и записать его более подробно:
fn f<F>(mut x: Vec<F>) -> F {
x.drain(..).next().unwrap()
}
Если вы полностью настроены на сопоставление с образцом, вы можете вместо этого использовать Itertools::tuples()
для сопоставления с кортежами:
use itertools::Itertools; // 0.9.0
fn f<F>(mut x: Vec<F>) -> F {
match x.drain(..).tuples().next() {
Some((a, _)) => a,
None => panic!()
}
}