如果标准 golang big.Int 函数接受两个参数并返回一个值,为啥它会使用接收器?

Posted

技术标签:

【中文标题】如果标准 golang big.Int 函数接受两个参数并返回一个值,为啥它会使用接收器?【英文标题】:Why does standard golang big.Int function use the receiver if it takes two arguments and returns a value?如果标准 golang big.Int 函数接受两个参数并返回一个值,为什么它会使用接收器? 【发布时间】:2021-11-05 08:59:38 【问题描述】:

功能:

// Mod sets z to the modulus x%y for y != 0 and returns z.
// If y == 0, a division-by-zero run-time panic occurs.
// Mod implements Euclidean modulus (unlike Go); see DivMod for more details.
func (z *Int) Mod(x, y *Int) *Int 

如果我想在条件中使用函数,我需要创建一个临时变量以避免被覆盖:

var tmp big.Int
for tmp.Mod(x, y).Cmp(z) == 0 
    这样做有什么实际好处吗? 我可以在不使用临时变量的情况下重写我的代码吗?

【问题讨论】:

1.是的,通常它允许重用(创建昂贵的)big.Int。 2. 不。不是你的情况(假设这是伪代码。) 【参考方案1】:

通常接收器用于结果,因此您可以选择重用现有的big.Int 实例。如果您不想重复使用现有的,您可以为结果创建一个新的并在其上调用方法。

math/big的包文档中提到了这一点:

通过始终通过接收器传递结果值,可以更好地控制内存使用。操作不必为每个结果分配新内存,而是可以重用为结果值分配的空间,并在进程中用新结果覆盖该值。

结果也会返回,因此您可以链接调用。包文档中也提到了这一点:

例如,(*Int).Add 的参数被命名为 x 和 y,因为接收者指定了结果目标,所以它被称为 z:

func (z *Int) Add(x, y *Int) *Int

这种形式的方法通常也会返回传入的接收者,以启用简单的调用链。

所以你可以这样做:

one := big.NewInt(1)
two := big.NewInt(2)
three := big.NewInt(3)

sum := new(big.Int)
sum.Add(sum, one).Add(sum, two).Add(sum, three)
fmt.Println(sum)

哪个会输出(在Go Playground上试试):

6

如果您不想为操作结果重用现有值,您可以像这样分配一个新值:

one := big.NewInt(1)
two := big.NewInt(2)

fmt.Println(new(big.Int).Add(one, two))

打印3(在Go Playground 上试试)。

【讨论】:

以上是关于如果标准 golang big.Int 函数接受两个参数并返回一个值,为啥它会使用接收器?的主要内容,如果未能解决你的问题,请参考以下文章

Golang标准库——math

Golang 持久通道接受来自多个函数调用的输入

lambda表达式和for_each

golang中的三个点 '...' 的用法

Golang "..."用法

大整数除法表示为 C++ 中的字符串