I can use methods like Text() on a big.Int and it works fine, but if I return a big.Int then use "myfunc().Text()" throws an error, whereas if I return a *big.Int, I get no error. Why can I use Text() on a big.Int, *big.Int, and on a function that returns *big.Int but not on a function whose return value is big.Int?
https://play.golang.org/p/ovgeQDHFstP
Based on this and other behavior (such as how it prints), it seems like *big.Int is the type that is intended for use, is that correct?
Also, if I make and use a variable of type big.Int or *big.Int, it is passed by reference. That's fine. But if I wanted to pass one by value, how is that best done?
Should I make a new big.Int and set it to the original value using Set() and pass that? Or should I pass the original big.Int in, and copy its value to a new big.Int using Set() inside the function? Or is there some other, better way of doing it?
https://golang.org/pkg/math/big/ the Text()
method has a pointer receiver, which means that you can only call a.Text()
if a is *big.Int
.
*big.Int
is a pointer to big.Int
, see https://play.golang.org/p/dD70b0tPeGp for a fixed version of your code
The Text()
method is defined for receiver type *big.Int
, so obviously you can call it on variables of that type and on return values of functions returning *big.Int
. You can also call it on variables of type big.Int
, because Go automatically takes the address of a variable when you're trying to call its pointer methods, just to save you the trouble of typing an extra ampersand.
However you can't call it on return value of a function returning big.Int
, because that value is not addressable. Here's what the spec says about addressability:
For an operand x of type T, the address operation &x generates a pointer of type *T to x. The operand must be addressable, that is, either a variable, pointer indirection, or slice indexing operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array. As an exception to the addressability requirement, x may also be a (possibly parenthesized) composite literal.
Your return value is none of those things, so you can't use the pointer method any more than you can write foo := &myFunc()
. To work around this, you could save the return value on a variable to make it addressable. But most likely your function should return a pointer in the first place.
Also note that there are no references in Go. Everything is passed by value, and pointers are values just like any other.