В мутагене, я инъекционный различные мутации в коде. Одна вещь, которую я хотел бы мутировать, - это шаблон, if let Ok(x) = y {.. }
. Однако это представляет собой сложную задачу, так как я не могу знать тип y
- пользователь мог бы создать собственное перечисление с унарным вариантом Ok
. Я все еще могу оппортунистически мутировать его для случаев, когда у нас действительно есть Result
, тип ошибки которого реализует значение по Default
используя свойство, которое выглядит следующим упрощенным:
#![feature(specialization)]
pub trait Errorer {
fn err(self, mutate: bool) -> Self;
}
impl<X> Errorer for X {
default fn err(self, _mutate: bool) -> Self {
self
}
}
impl<T, E> Errorer for Result<T, E>
where
E: Default,
{
fn err(self, mutate: bool) -> Self {
if mutate {
Err(Default::default())
} else {
self
}
}
}
Увы, не так много ошибок, которые реализуют Default
, поэтому это не слишком полезно. Даже реализация для Result<T, Box<Error>>
даст нам больше шансов для доллара (и будет вполне возможно). Однако, учитывая, что мне все равно, что код действительно проверяет ошибку, мне интересно, могу ли я сделать общую реализацию, расширив мутацию вышеуказанного кода до
match Errorer::err(y, mutation) {
Ok(x) => { .. }
Err(x) => { mem::forget(x); }
}
и иметь err
возвращать Err(mem::uninitialized())
при мутировании - так ли это поведение безопасно? Примечание. Я возвращаю Err(mem::uninitialized())
из метода, только для mem::forget
его позже. Я не вижу, чтобы это могло паниковать, поэтому мы должны предположить, что ценность будет действительно забыта.
Является ли это определенным поведением или я должен ожидать носовых демонов?