对多个方法参数使用相同的引用

Using same reference for multiple method parameters

我会先说我是 Rust 的新手,而且我仍在思考借用检查器的语义。我对为什么它不喜欢我的代码有一些了解,但我不确定如何以惯用的方式解决它。

我在 Rust 中有一个方法接受 3 个参数,签名看起来像这样:

fn do_something(&mut self, mem: &mut impl TraitA, bus: &mut impl TraitB, int_lines: &impl TraitC) -> ()

我还有一个 struct 实现了所有这三个特征;但是,当我尝试对多个参数使用相同的引用时,借用检查器会抱怨:

cannot borrow `*self` as mutable more than once at a time

还有:

cannot borrow `*self` as immutable because it is also borrowed as mutable

我的第一个问题是这是否是借用检查器的缺点(无法识别正在传递相同的引用),还是设计使然(我怀疑是这种情况,因为从被调用的方法每个引用都是不同的,因此每个引用的所有权可以分开考虑。

我的第二个问题是惯用的方法是什么。我看到的两个解决方案是:

a) 将所有三个特征合二为一。虽然考虑到我的库的设计,这在技术上是微不足道的,但它会使代码明显不那么干净,因为这三个特征用于与 struct 状态的不相关部分进行交互。此外,由于这是一个库(do_something 方法是测试的一部分),它阻碍了将状态分离为单独的 structs.

的可能性

b) 将 struct 状态的各个部分移动到单独的 struct 中,然后由主要 struct 拥有。这对我来说似乎是更好的选择,尤其是因为它不需要对库代码本身进行任何更改。

如果我遗漏了另一个解决方案,或者是否有办法说服借用检查员接受我的原始设计,请告诉我。

借用检查器正在按设计运行。它只知道你将三个不同的可变引用传递给同一个函数:它不知道函数将如何处理这些,即使它们碰巧是对同一个结构的引用。在函数中,它们是对同一结构的三个不同的可变引用。

如果三个不同的特征代表三个不同的功能方面,那么您最好的方法可能是将结构拆分为不同的结构,每个结构实现一个特征,正如您所提议的那样。

如果您希望保留单个结构,并且函数将始终使用单个结构调用,那么您可以像这样只传入一次:

fn do_something(&mut self, proc: &mut (impl TraitA + TraitB + TraitC)) -> () { ... }