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

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

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天全站免登陆