跳转至

BigUint操作

原文:https://docs.elrond.com/developers/best-practices/biguint-operations

## BigUint 操作

BigUint只是实际表示的句柄,类似于系统文件句柄的工作方式,所以它只是一个以i32为成员的结构,表示句柄。所有的操作都必须通过 API 函数来完成,传递结果、第一个操作数、第二个操作数的句柄。使用 Rust 的运算符重载特性,我们能够覆盖算术运算符,并提供一种添加BigUint的简单方法,就像原始数字类型一样。

尽管如此,您可能很容易遇到想要多次使用同一个号码的情况。例如,假设您有 4 个BigUint:abcd,您想要执行以下操作:

c = a + b;
d = c + a; 

你会很快意识到这是行不通的,因为 Rust 的所有权系统。a在第一次操作后被消耗,您可能会看到这样的错误:

move occurs because `a` has type `<Self as ContractBase>::BigUint`, which does not implement the `Copy` trait 

解决这个问题最简单的方法就是简单的克隆a

c = a.clone() + b;
d = c + a; 

错误现在已经没有了,但是在幕后,这比简单地复制句柄要复杂得多。a.clone()创建一个全新的BigUint,从原来的a复制字节。

这个可以借用a来解决。+和其他操作是为BigUint的引用而定义的,所以这可以改写为:

c = &a + &b;
d = c + a; 

避免创建额外的BigUint的另一个例子是使用多个参数执行操作:

e = a + b + c + d; 

或者,如果您想保留实例(不能将拥有的BigUint添加到&BigUint,所以您也必须借用结果):

e = &((&(&a + &b) + &c) + &d; 

在这两种情况下,这将执行以下 API 调用:

temp1 = bigIntNew();
bigIntAdd(temp1, a, b);

temp2 = bigIntNew();
bigIntAdd(temp2, temp1, c);

temp3 = bigIntNew();
bigIntAdd(temp3, temp2, d); 

同样,创建 3 个新的BigUints,一个用于a + b的结果,一个用于(a + b) + c的结果,一个用于在e结束的最终结果。这可以通过以下方式重写代码来优化:

e = BigUint::zero();
e += &a;
e += &b;
e += &c;
e += &d; 

这会创建一个BigUint而不是 3 个。

当然,这些都是微不足道的例子,但我们希望这能澄清一些关于如何工作以及如何充分利用它们的困惑。



回到顶部