如何避免在Rust中为可变和不可变引用编写重复的访问器函数? [英] How to avoid writing duplicate accessor functions for mutable and immutable references in Rust?

查看:86
本文介绍了如何避免在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;
    }
}


这是代码库的更详细摘录,其中将不可变的返回参数强制转换为可变的,以支持函数的不可变版本和可变版本.它使用包装的指针类型(对于不可变和可变引用,为ConstPMutP),但是该函数的逻辑应该清楚.


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都是不同类型.在这种情况下,您的问题与询问如何避免为StringHashMap编写重复的访问器函数"相同.

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中为可变和不可变引用编写重复的访问器函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆