Go is a statically typed programming language, meaning that data types are tied to variables. If you declare a variable as int
to store numerical values, you cannot store a string
in it. This rule works in the reverse direction as well.
Static typing protects developers from errors where the program expects one data type and gets another. However, this strict binding can be limiting when performing certain operations. Go provides type conversion (or type casting) to overcome this limitation. This formal process allows developers to convert integer values to floating-point numbers, strings to numbers, and vice versa. This article will help you understand how to perform such conversions.
The basic types in Go are as follows:
bool
— Boolean values: true
or false
string
— Stringsint
, int8
, int16
, int32
, int64
— Signed integer typesuint
, uint8
, uint16
, uint32
, uint64
, uintptr
— Unsigned integer typesbyte
— Alias for uint8
rune
— Alias for int32
float32
, float64
— Floating-point numberscomplex64
, complex128
— Complex numbersThe types int
, uint
, and uintptr
have a width of 32 bits in 32-bit systems and 64 bits in 64-bit systems. When you need an integer value, you should use int unless you have a specific reason for using a sized or unsigned integer type.
Go does not have a char
data type. The language uses byte
and rune
to represent character values. byte
represents ASCII characters, while rune
represents a broader set of Unicode characters encoded in UTF-8.
To define characters in Go, you enclose them in single quotes like this: 'a'
. The default type for character values is rune
. If you do not explicitly declare the type when assigning a character value, Go will infer the type as rune
:
var firstLetter = 'A' // Type inferred as `rune`
You can explicitly declare a byte variable like this:
var lastLetter byte = 'Z'
Both byte
and rune
are integer types. For example, a byte
with the value 'a'
is converted to the integer 97. Similarly, a rune with the Unicode value '♥'
is converted to the corresponding Unicode code point U+2665
, where U+
indicates Unicode, and the numbers are in hexadecimal, which is essentially an integer.
Here's an example:
package main
import "fmt"
func main() {
var myByte byte = 'a'
var myRune rune = '♥'
fmt.Printf("%c = %d and %c = %U\n", myByte, myByte, myRune, myRune)
}
Output:
a = 97 and ♥ = U+2665
When you need to convert from int
to string
or vice versa, you essentially take the type initially assigned to a variable and convert it to another type. As mentioned earlier, Go strictly formalizes these actions. The examples in this article will help you understand the basics of such conversions.
Converting numeric types can be useful when solving various tasks. For example, we decided to add a calculator to the website. It should perform only one operation: division. The main requirement is that the result be accurate down to the last digit.
However, when dividing two integer variables, the result may be inaccurate. For example:
package main
import "fmt"
func main() {
var first int = 15
var second int = 6
var result = first / second
fmt.Println(result)
}
Output:
2
After executing this code, you get 2
. The program outputs the nearest integer quotient, but this is far from the precise division you need. Such a calculator is not useful.
To improve the accuracy, you need to cast both variables to float
. Here's how you can do it:
package main
import "fmt"
func main() {
var first int = 15
var second int = 6
var result = float64(first) / float64(second)
fmt.Println(result)
}
Output:
2.5
Now the output will be precise — 2.5
. It was quite easy to achieve by simply wrapping the variables with the float64()
or float32()
conversion functions. Now the calculator works as expected. Product metrics are not a concern, as the feature is technically implemented correctly.
You can also divide numbers without explicitly converting them to float
. When you use floating-point numbers, other types are automatically cast to float
. Try this code:
package main
import "fmt"
func main() {
a := 5.0 / 2
fmt.Println(a)
}
Output:
2.5
Even though you didn’t explicitly use the float64()
or float32()
wrapper in the code, Go's compiler automatically recognizes that 5.0
is a floating-point number and performs the division with the floating-point precision. The result is displayed as a floating-point number.
In the first example with division, you explicitly cast the integers to float
using the float64()
function. Here’s another example of converting from int64
to float64
:
package main
import "fmt"
func main() {
var x int64 = 57
var y float64 = float64(x)
fmt.Printf("%.2f\n", y)
}
Output:
57.00
The two zeros after the decimal point appear because we added the %.2f\n
format specifier. Instead of 2
, you could specify any other number, depending on how many decimal places you want to display.
You can also convert from float
to int
. Here's an example:
package main
import "fmt"
func main() {
var f float64 = 409.8
var i int = int(f)
fmt.Printf("f = %.3f\n", f)
fmt.Printf("i = %d\n", i)
}
Output:
f = 409.800
i = 409
In this example, the program prints f = 409.800
with three decimal places. In the second print statement, the float
is first converted to int
, and the decimal part is discarded. Note that Go does not perform rounding, so the result is 409
without any rounding to the nearest integer.
In Golang, we can convert a number to a string using the method strconv.Itoa
. This method is part of the strconv package in the language's standard library.
Run this code:
package main
import (
"fmt"
"strconv"
)
func main() {
a := strconv.Itoa(12)
fmt.Printf("%q\n", a)
}
The result should be the string "12"
. The quotes in the output indicate that this is no longer a number.
In practice, such string-to-number and number-to-string conversions are often used to display useful information to users. For example, if you're building an online store, you can host it at Hostman, implement the core business logic, and fill it with products.
After some time, the product manager suggests improving the user profile. The user should see the amount they have spent and how much more they need to spend to reach the next level. To do this, you need to display a message in the user profile that consists of a simple text and a set of digits.
Try running this code:
package main
import (
"fmt"
)
func main() {
user := "Alex"
sum := 50
fmt.Println("Congratulations, " + user + "! You have already spent " + lines + " dollars.")
}
The result will be an error message. You cannot concatenate a string and a number. The solution to this problem is to convert the data in Go.
Let's fix the code by converting the variable lines
to a string:
package main
import (
"fmt"
"strconv"
)
func main() {
user := "Alex"
sum := 50
fmt.Println("Congratulations, " + user + "! You have already spent " + strconv.Itoa(sum) + " dollars.")
}
Now, there will be no error, and the output will display the correct message with the proper set of digits. Of course, this is a simplified example. In real projects, the logic is much more complex and challenging. However, knowing the basic operations helps avoid a large number of errors. This is especially important when working with complex systems.
Let's go back to our example. The product manager comes again and says that customers want to see the exact total amount of their purchases in their profile, down to the pennies. An integer value won't work here. As you already understood from the examples above, all digits after the decimal point are simply discarded. To make sure the total purchase amount in the user profile is displayed correctly, we will convert not an int
, but a float
to a string.
For this task, there is a method fmt.Sprint
, which is part of the fmt
package.
package main
import (
"fmt"
)
func main() {
fmt.Println(fmt.Sprint(421.034))
f := 5524.53
fmt.Println(fmt.Sprint(f))
}
To verify that the conversion was successful, concatenate the total with the string. For example:
package main
import (
"fmt"
)
func main() {
f := 5524.53
fmt.Println("Alex spent " + fmt.Sprint(f) + " dollars.")
}
There is no error now, and the information message correctly displays the floating-point number. Customers can see how much money they've spent in your store, with all expenses accounted for down to the penny.
A common reverse task is to convert a string into numbers. For example, you have a form where the user enters their age or any other numeric values. The entered data is saved in the string format. Let's try working with this data— for instance, performing a subtraction:
package main
import (
"fmt"
)
func main() {
lines_yesterday := "50"
lines_today := "108"
lines_more := lines_today - lines_yesterday
fmt.Println(lines_more)
}
The result of running this code will be an error message, as subtraction cannot be applied to string values. To perform mathematical operations on data stored as strings, you need to convert them to int or float.
The choice of method depends on the type you will convert the string to. If you are working with integers, use the strconv.Atoi
method. For floating-point numbers, use the strconv.ParseFloat
method.
package main
import (
"fmt"
"log"
"strconv"
)
func main() {
lines_yesterday := "50"
lines_today := "108"
yesterday, err := strconv.Atoi(lines_yesterday)
if err != nil {
log.Fatal(err) }
today, err := strconv.Atoi(lines_today)
if err != nil {
log.Fatal(err)
}
lines_more := today - yesterday
fmt.Println(lines_more)
}
In this example, you use the if
operator to check whether the conversion was successful. If an error occurs, the program will terminate, and the error information will be saved in the log. If the conversion is successful, the output will give you the correct result: 108 - 50 = 58.
If you try to convert a string that does not contain a numerical value in the same way, you will receive an error message:
strconv.Atoi: parsing "not a number": invalid syntax
Try running this code:
package main
import (
"fmt"
"strconv"
)
func main() {
a := "not a number"
b, err := strconv.Atoi(a)
fmt.Println(b)
fmt.Println(err)
}
The code from the example above will fail because you are trying to convert a string whose value is not a number into a numeric type.
Strings can also be converted to byte slices and back using the []byte()
and string()
constructs.
package main
import (
"fmt"
)
func main() {
a := "hostman"
b := []byte(a)
c := string(b)
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
}
In this function, you save the string to variable a
, then convert the same string into a byte slice and save it to variable b
, then turn the byte slice into a string and save the result to variable c
. The output will be like this:
hostman
[104 111 115 116 109 97 110]
hostman
This simple example shows that you can easily convert strings to byte slices and back.
In this article, we only covered the basics. We looked at the available data types and how to perform type conversion in Go.
If you want to learn more, explore the language documentation or at least the "A Tour of Go" tutorial — it's an interactive introduction to Go divided into three sections. The first section covers basic syntax and data structures, the second discusses methods and interfaces, and the third introduces Go's concurrency primitives. Each section concludes with several exercises so you can practice what you've learned.
In addition, you can deploy Go applications (such as Beego and Gin) on our app platform.