Simply Use the int() cast function
I have the following function, it works flawlessly
func (r *system) Quantity() int32 {
// r.info.Quantity is type int
return int32(r.info.Quantity)
}Now I'm trying to cast it to *int32
func (r *system) Quantity() *int32 {
// r.info.Quantity is type int
return int32(&r.info.Quantity)
}
But i get the following error cannot use &r.info.Quantity (type *int) as type *int32 in return argument, and of course it seems logic...is there a way to achieve this?
How to convert [ ]int32 to [ ]int in Go - Stack Overflow
Convert uint32 to int in Go - Stack Overflow
numeric - Go: convert big.Int to regular integer (int, int32, int64) - Stack Overflow
go - int vs int32 return value - Stack Overflow
Simply Use the int() cast function
The Go Programming Language Specification
Conversions
Conversions are expressions of the form
T(x)whereTis a type andxis an expression that can be converted to typeT.
For example,
size := binary.BigEndian.Uint32(b[4:])
n, err := rdr.Discard(int(size))
From what I understand, the size of the int type in Go is platform dependent.
From the docs (tour):
The int, uint, and uintptr types are usually 32 bits wide on 32-bit systems and 64 bits wide on 64-bit systems. When you need an integer value you should use int unless you have a specific reason to use a sized or unsigned integer type.
So, on a 32-bit system, if I did something like this:
var myUint32 uint32 = 4294967295 // max positive value for uint32 myInt := int(myUint32)
what would happen to myInt on a 32-bit system? I can't seem to find docs for this. Would the bitwise value remain the same in memory (and using a bit as a sign bit)? Or would there be truncation of some sort? I am unsure. I also don't have a quick way to test this out.
backstory, I have code in review that was suggested to be written like this:
func myFunc (a, b uint32) int {
return int(a) - int(b)
}I have a really bad feeling about this, especially since our code planned to be open source. There is no guarantee what architecture this will run on. But I need solid evidence argue we shouldn't do this.
One line answer is fmt.Sprint(i).
Anyway there are many conversions, even inside standard library function like fmt.Sprint(i), so you have some options (try The Go Playground):
1- You may write your conversion function (Fastest):
func String(n int32) string {
buf := [11]byte{}
pos := len(buf)
i := int64(n)
signed := i < 0
if signed {
i = -i
}
for {
pos--
buf[pos], i = '0'+byte(i%10), i/10
if i == 0 {
if signed {
pos--
buf[pos] = '-'
}
return string(buf[pos:])
}
}
}
2- You may use fmt.Sprint(i) (Slow)
See inside:
// Sprint formats using the default formats for its operands and returns the resulting string.
// Spaces are added between operands when neither is a string.
func Sprint(a ...interface{}) string {
p := newPrinter()
p.doPrint(a)
s := string(p.buf)
p.free()
return s
}
3- You may use strconv.Itoa(int(i)) (Fast)
See inside:
// Itoa is shorthand for FormatInt(int64(i), 10).
func Itoa(i int) string {
return FormatInt(int64(i), 10)
}
4- You may use strconv.FormatInt(int64(i), 10) (Faster)
See inside:
// FormatInt returns the string representation of i in the given base,
// for 2 <= base <= 36. The result uses the lower-case letters 'a' to 'z'
// for digit values >= 10.
func FormatInt(i int64, base int) string {
_, s := formatBits(nil, uint64(i), base, i < 0, false)
return s
}
Comparison & Benchmark (with 50000000 iterations):
s = String(i) takes: 5.5923198s
s = String2(i) takes: 5.5923199s
s = strconv.FormatInt(int64(i), 10) takes: 5.9133382s
s = strconv.Itoa(int(i)) takes: 5.9763418s
s = fmt.Sprint(i) takes: 13.5697761s
Code:
package main
import (
"fmt"
//"strconv"
"time"
)
func main() {
var s string
i := int32(-2147483648)
t := time.Now()
for j := 0; j < 50000000; j++ {
s = String(i) //5.5923198s
//s = String2(i) //5.5923199s
//s = strconv.FormatInt(int64(i), 10) // 5.9133382s
//s = strconv.Itoa(int(i)) //5.9763418s
//s = fmt.Sprint(i) // 13.5697761s
}
fmt.Println(time.Since(t))
fmt.Println(s)
}
func String(n int32) string {
buf := [11]byte{}
pos := len(buf)
i := int64(n)
signed := i < 0
if signed {
i = -i
}
for {
pos--
buf[pos], i = '0'+byte(i%10), i/10
if i == 0 {
if signed {
pos--
buf[pos] = '-'
}
return string(buf[pos:])
}
}
}
func String2(n int32) string {
buf := [11]byte{}
pos := len(buf)
i, q := int64(n), int64(0)
signed := i < 0
if signed {
i = -i
}
for {
pos--
q = i / 10
buf[pos], i = '0'+byte(i-10*q), q
if i == 0 {
if signed {
pos--
buf[pos] = '-'
}
return string(buf[pos:])
}
}
}
The Sprint function converts a given value to string.
package main
import (
"fmt"
)
func main() {
var sampleInt int32 = 1
sampleString := fmt.Sprint(sampleInt)
fmt.Printf("%+V %+V\n", sampleInt, sampleString)
}
// %!V(int32=+1) %!V(string=1)
See this example.
You convert them with a type "conversion"
var a int
var b int64
int64(a) < b
When comparing values, you always want to convert the smaller type to the larger. Converting the other way will possibly truncate the value:
var x int32 = 0
var y int64 = math.MaxInt32 + 1 // y == 2147483648
if x < int32(y) {
// this evaluates to false, because int32(y) is -2147483648
Or in your case to convert the maxInt int64 value to an int, you could use
for a := 2; a < int(maxInt); a++ {
which would fail to execute correctly if maxInt overflows the max value of the int type on your system.
I came here because of the title, "How to convert an int64 to int in Go?". The answer is,
int(int64Var)
I am a bit concerned about a piece of code I wrote. It seems to work but I did not quite expect it to...
How does type conversion exactly work in Go when I convert a int32 to uint64 and then back to int32. I was somewhat scared that funny business might happen.
To give practical context of what I am doing. I have data like:
type data struct {
a uint16
b uint8
c uint8
d int32
}
Instead of using a data struct I want to package all the values in a single uint64 like:
data := uint64(a) | uint64(b)<<16 | uint64(c)<<24 | uint64(d)<<32
and then unpack it like (shifting back and applying a bit mask if necessary):
d := int32(data>>32)
my worries were around:
data = uint64(int32(d))
I was worried that it would try to do some conversion from int32 with negative values. But running some tests all it seems to be doing is padding or truncating bits and interpreting the two's compliment int values as uint.
Is this all safe and correct or am I about to run into nightmarish bugs?
Edit: In essence what I am asking with go type conversions does this hold for every value of d of type int32 :
d == int32(uint64(d))