Home > OS >  Why does standard golang big.Int function use the receiver if it takes two arguments and returns a v
Why does standard golang big.Int function use the receiver if it takes two arguments and returns a v

Time:11-06

The function:

// 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 {

If I want to use a function in conditions, I need to create a temporary variable to avoid being overwritten:

var tmp big.Int
for tmp.Mod(x, y).Cmp(z) == 0 {
  1. Is there any practical benefit from this?
  2. Can I rewrite my code without using a temporary variable?

CodePudding user response:

Typically the receiver is used for the result so you have the option to reuse an existing big.Int instance. If you don't want to reuse an existing one, you may create a new one for the result and call the method on that.

This is mentioned in the package doc of math/big:

By always passing in a result value via the receiver, memory use can be much better controlled. Instead of having to allocate new memory for each result, an operation can reuse the space allocated for the result value, and overwrite that value with the new result in the process.

The result is also returned so you can chain invocations. This is also mentioned in the package doc:

For instance, the arguments for (*Int).Add are named x and y, and because the receiver specifies the result destination, it is called z:

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

Methods of this form typically return the incoming receiver as well, to enable simple call chaining.

So you may do something like this:

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)

Which will output (try it on the Go Playground):

6

If you don't want to reuse an existing value for the result of an operation, you may allocate a new like this:

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

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

Which prints 3 (try it on the Go Playground).

  •  Tags:  
  • go
  • Related