考虑“大”结构的情况,例如包含多个BigInt
变量的结构。例如:
struct BigStruct {
x: BigInt,
y: BigInt,
z: BigInt,
}
我目前对Rust的理解如下:
这些都是出于性能原因。
这种结构主要是只读的,因为它的参数一旦设置就不会改变。尽管如此,该结构的元素通常用于生成新元素(通过运算符覆盖),如下例所示:
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>
来覆盖添加。
答案 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
在这种情况下,算术非常简单。这种方法有一些缺点: