Use values for small, immutable types like int or string to avoid copying overhead, and use pointers for large structs or when you need to modify the original data. In the gmp example, Int is a struct wrapping C.mpz_t, so methods like Set take *Int to modify the underlying C memory directly without copying the entire struct.
// Value: small, immutable, copied on pass
func Add(a, b int) int { return a + b }
// Pointer: large struct or needs modification
func (z *Int) Set(x *Int) *Int {
z.doinit()
C.mpz_set(&z.i[0], &x.i[0])
return z
}