有幾次,我碰到了一個場景,在這個場景中,可變參數和不可變參考都需要訪問器方法。如何避免在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';我很想看看人們會做什麼,也許有些特質(與關聯類型)可以通過可變性進行抽象。 –