Несколько раз, я столкнулся с сценарием, где необходим метод доступа для обеих изменяемых и неизменяемых ссылок.Как избежать дублирования функций доступа для изменяемых и неизменных ссылок в Rust?
Для ~ 3 строк не проблема дублировать логику, но когда логика становится более сложной, неплохо скопировать большие блоки кода.
Я хотел бы иметь возможность повторно использовать код для обоих.
Предоставляет ли Rust некоторый способ справиться с этим лучше, чем скопировать код или использовать unsafe
?
.: например
impl MyStruct {
pub fn get_foo(&self) -> &Bar {
// ~20 lines of code
// --- snip ---
return bar;
}
pub fn get_foo_mut(&mut self) -> &mut Bar {
// ~20 lines of code
// (exactly matching previous code except `bar` is mutable)
// --- snip ---
return bar;
}
}
Вот более подробный отрывок кода базы, где неизменный обратный аргумент был приведен к изменяемым для поддержки как неизменные и изменяемые версии функции. Это использует тип обернутого указателя (ConstP
и MutP
для неизменяемых и изменяемых ссылок), но логика функции должна быть ясной.
pub fn face_vert_share_loop<V, F>(f: F, v: V) -> LoopConstP
where V: Into<VertConstP>,
F: Into<FaceConstP>
{
into_expand!(f, v);
let l_first = f.l_first.as_const();
let mut l_iter = l_first;
loop {
if l_iter.v == v {
return l_iter;
}
l_iter = l_iter.next.as_const();
if l_iter == l_first {
break;
}
}
return null_const();
}
pub fn face_vert_share_loop_mut(f: FaceMutP, v: VertMutP) -> LoopMutP {
let l = face_vert_share_loop(f, v);
return unsafe {
// Evil! but what are the alternatives?
// Perform an unsafe `const` to `mut` cast :(
// While in general this should be avoided,
// its 'OK' in this case since input is also mutable.
l.as_mut()
};
}
Чтобы уточнить, 'MyStruct' как-то сродни карте, а 20 строк кода, которые вы используете, используются для получения ссылки на' Bar'?Это может быть, потому что это утро, но у меня есть некоторые трудности с тем, как именно это происходит, поэтому трудно оценить потенциальные ответы, которые я придумал ... не могли бы вы придумать MCVE? –
Добавлен пример функции, где мне это нужно. Выложил бы что-то более простое и самодостаточное - но более упрощая проблему * может * использовать некоторую особенность Rust, которая не может использоваться в более вовлеченных случаях. – ideasman42
Теперь с вашим примером это яснее, спасибо. У меня были те же проблемы на C++ и регулярно использовались 'const_cast' аналогично вашему примеру; Мне интересно узнать, что люди смогут сделать, может быть, что-то с чертами (со связанными типами) доступно для абстрактной над изменчивостью. –