只使用引用最“惯用/高效”的“大”结构?

时间:2016-06-28 08:39:44

标签: rust

考虑“大”结构的情况,例如包含多个BigInt变量的结构。例如:

struct BigStruct {
    x: BigInt,
    y: BigInt,
    z: BigInt,
}

我目前对Rust的理解如下:

  1. 我不应该在这样的结构上实现Copy。
  2. 我应该通过引用来操纵它。
  3. 这些都是出于性能原因。

    这种结构主要是只读的,因为它的参数一旦设置就不会改变。尽管如此,该结构的元素通常用于生成新元素(通过运算符覆盖),如下例所示:

    let b1: BigStruct = BigStruct { ... } // Rarely change
    let b2: BigStruct = BigStruct { ... } // Rarely change
    let b3: BigStruct = &b1 + &b2 // Often combined by operations
    

    您是否可以确认我的方法(没有Copy,所有引用)对于此用例是最惯用/最有效的?它似乎至少有两个缺点:

    • 如果有人想使用我的代码,他们需要考虑是否应该使用上下文中的引用。我想隐藏这种复杂性以使最简单的API成为可能。

    • 我必须覆盖每个运算符两次。例如,我必须提供Add<Self>Add<&Self>来覆盖添加。

1 个答案:

答案 0 :(得分:0)

可以解决最初问题的两个(部分)解决方案:

获取完整参考资料,但不是问题

中所述
  • 仅操纵&BigStruct;
  • &BigStruct作为函数参数传递;
  • 仅为&BigStruct覆盖运算符。

上一个例子是:

let b1: &BigStruct = &BigStruct { ... } 
let b2: &BigStruct = &BigStruct { ... } 
let b3: &BigStruct = &(b1 + b2) 

这种方法的主要问题是函数和运算符将返回BigStruct而不是&BigStruct这对用户来说不方便,特别是在进行算术运算时(它强制每次添加&执行操作的时间)。

使用拥有的指针

Pointers in Rust : a guide中提到的,这个用例可能是使用指针提高效率的合法例外。具体而言,我们可以:

  • 仅操纵Box<BigStruct>;
  • 在函数中传递并返回Box<BigStruct>;
  • 仅为Box<BigStruct>覆盖运算符。

上一个例子是:

let b1: Box<BigStruct> = Box::new(BigStruct { ... }) 
let b2: Box<BigStruct> = Box::new(BigStruct { ... }) 
let b3: Box<BigStruct> = b1 + b2 

在这种情况下,算术非常简单。这种方法有一些缺点:

  • 用指针明确地工作不是惯用的Rust;
  • 从函数返回指针被认为是一个糟糕的Rust实践。