考虑“大”结构的情况,例如包含多个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和return
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 - 对于“大型”结构,仅使用引用最惯用/最有效吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38071167/