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

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

我目前对锈的理解是:
我不应该在这样的结构上实现复制。
我应该通过引用来操纵它。
这两个都是出于性能原因。
这个结构主要是只读的,因为一旦设置了参数,它的参数通常不会改变。不过,该结构的元素通常用于生成新的元素(通过运算符重写),如下例所示:
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>来覆盖加法。

最佳答案

可能解决初始问题的两个(部分)解决方案:
完整的推荐信,但不要像问题中描述的那样
仅操作&BigStruct
Pass&BigStruct作为函数参数;
仅覆盖&BigStruct的运算符。
前面的例子是:

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

这种方法的主要问题是函数和运算符将返回BigStruct而不是&BigStruct,这对用户特别是在做算术时是不方便的(每次执行操作时都会强制添加一个&)。
使用自有指针
正如Pointers in Rust : a guide中提到的,这个用例可能是使用指针提高效率的合法例外。具体来说,我们可以:
仅操作Box<BigStruct>
函数中的Pass和returnBox<BigStruct>
仅覆盖Box<BigStruct>的运算符。
前面的例子是:
let b1: Box<BigStruct> = Box::new(BigStruct { ... })
let b2: Box<BigStruct> = Box::new(BigStruct { ... })
let b3: Box<BigStruct> = b1 + b2

在这种情况下,算术是非常严格的。尽管如此,这种方法仍有一些缺点:
明确地使用指针并不是习惯性的生锈;
从函数返回指针被认为是一种糟糕的生锈实践。

关于rust - 对于“大型”结构,仅使用引用最惯用/最有效吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38071167/

10-12 06:54