问题描述
有几次,我遇到了这样的情况:可变和不可变的引用都需要访问器方法.
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":
- Parameterisation over mutability
- Dealing with &/&mut in data structures: abstract over mutability or split types?
- A safe way to reuse the same code for immutable and mutable variants of a function?
- Abstracting over mutability in Rust
- "Mutability polymorphism"
- etc. etc. etc.
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中为可变和不可变引用编写重复的访问器函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!