如何避免在 Rust 中为可变和不可变引用编写重复的访问器函数? [英] How to avoid writing duplicate accessor functions for mutable and immutable references in Rust?
问题描述
有几次,我遇到过这样的情况,即可变引用和不可变引用都需要访问器方法.
A few times, I've run into the scenario where an accessor method is needed for both mutable and immutable references.
对于 ~3 行,复制逻辑不是问题,但是当逻辑变得更复杂时,复制粘贴大块代码是不好的.
For ~3 lines it isn't a problem to duplicate the logic, but when the logic gets more complex, it's not nice to copy-paste large blocks of code.
我希望能够为两者重复使用代码.
I'd like to be able to re-use the code for both.
Rust 是否提供了某种方式来处理这个问题,而不是复制粘贴代码,或者使用 unsafe
强制转换?
Does Rust provide some way handle this better then copy-pasting code, or using unsafe
casts?
例如:
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
用于不可变和可变引用),但函数的逻辑应该很清楚.
Here is a more detailed excerpt of a code-base where an immutable return argument was cast to mutable to support both immutable and mutable versions of a function. This uses a wrapped pointer type (ConstP
and MutP
for immutable and mutable references), but the logic of the function should be clear.
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()
};
}
推荐答案
你没有,真的.回想一下,T
、&T
和 &mut T
都是不同的类型.在这种情况下,您的问题与询问如何避免为 String
和 HashMap
编写重复的访问器函数"一样.
You don't, really. Recall that T
, &T
and &mut T
are all different types. In that context, your question is the same as asking "How to avoid writing duplicate accessor functions for String
and HashMap
".
Matthieu M 有正确的术语抽象可变性":
Matthieu M had the right terms "abstract over the mutability":
TL;DR 是 Rust 可能需要通过新功能进行增强以支持这一点.由于没有人成功,因此没有人 100% 确定需要哪些功能.目前最好的猜测是更高级的类型 (HKT).
The TL;DR is that Rust would likely need to be enhanced with new features to support this. Since no one has succeeded, no one is 100% sure which features those would need to be. The current best guess is higher kinded types (HKT).
这篇关于如何避免在 Rust 中为可变和不可变引用编写重复的访问器函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!