Select Page

Data Conversion in Go | Developer.com

Manoj Debnath
Published: January 20, 2023

Go Programming ``

Converting data from one type to another is a very common practice in programming. In Go (or Golang), a statically typed language, this is particularly necessary to manipulate data in many ways, such as converting values from int to float, concatenating numeric values to strings, and so forth. This programming tutorial illustrates different data conversion techniques typically used in Go programming.

Overview of Go Data Types

Data types in Go are used to classify the type of data – such as an integer, which is used to represent a non-fractional number, floating-point to represent fractional values, and strings to represent collection of alphanumeric values. Note that Go is a statically typed language, which means that if developers define a variable of a type it can store values of that type only. At a later point, if we decide to store another type of value (such as integer to string or vice versa) it is not possible; or rather, it is possible only through data type conversion. Go has three basic data types:

  • Bool: Represents boolean true or false values
  • Numeric: Numeric values cane be integer, floating-point, and complex types
  • String: Represents string or text values

Read: How to Work with Strings in Go and Golang

Golang Code Example: Data Types

Below is a quick Go code example showing how to store various data types in variables and then print those values to the users screen:

package main
import "fmt"
func main() {
	var boolVal bool = true
	var intVal int = 10
	var floatVal float32 = 1.22
	var strVal string = "Hello!"

	fmt.Println(boolVal)
	fmt.Println(intVal)
	fmt.Println(floatVal)
	fmt.Println(strVal)
}

Running this program in your integrated development environment (IDE) or code editor would result in the following output:

true
10
1.22
Hello!

Number Representation in Go

Early on in computing history, C compilers only supported 16-bit int and 32-bit long values for non-fractional numbers. With the ever-evolving times, C-based compilers have changed a lot and now have full support of 64-bit systems. However, the conversion from a type such as uint32_t – which represents a 32-bit unsigned integer to unsigned int – is not always safe.

The problem of unsafe conversion exists in C because of the core changes it has to make to assimilate the support for evolving systems. Go, being a more recent language, has provided explicit sized integer and floating point types from the very beginning. In Go, the type uint64 is always a 64-bit unsigned integer and uint16 is always a 16-bit signed integer. Go also provides int and uint types that are the native size of the machine, or at least 32-bit. Unlike C, which supports implicit cast between int to any explicitly sized types, Go does not support implicit type conversion. This is to ensure that no unsafe conversion occurs.

Go has many integer data types to pick from. Such as:

  • Signed: int, int8, int16, int32, int 64
  • Unsigned: uint, uint8, uint16, uint32, uint 64

Similarly, there are floating-point types, such as:

Other data types in go include: bool: bool and string: string.

Read: Best Online Courses to Learn Go and Golang

Golang Data Conversion

As mentioned, there is no implicit conversion from one number to another in Golang; instead, developers must use some of Go’s built-in functions to convert from one type to another. Below are some examples showing how to convert data types in Go:

var boolVal bool = true
var intVal int = 10
var intVal2 int32 = 10
var floatVal float32 = 1.22
var floatVal2 float64 = 2.34
var strVal string = "Hello!"

intVal = int(intVal2)
intVal2 = int32(floatVal)
floatVal2 = float64(floatVal)
floatVal = float32(intVal2)

We will dive further into what the above code means in the following sections.

How to Convert Strings and Numbers in Go

A typical conversion programmers need to perform is between strings and numbers. Go provides an exclusive package for string conversion known as strconv package. However, the simplest conversion is performed by the fmt package, while using functions like Printf and Scanf.

That being said, the strconv package is the standard for implementing conversion to – and from – string representation to basic data types. This package provides various functions to perform conversions. Developers can optionally specify the base of the number. Here is a very simple code example showing how to use fmt and strconv in Go:

package main

import (
	"fmt"
	"strconv"
)

func main() {
	var intVal int
	fmt.Scanf("%d", &intVal)
	strVal := strconv.FormatInt(int64(intVal), 10)
	fmt.Println(strVal)
	val, _ := strconv.ParseInt(strVal, 16, 64)
	fmt.Printf("%d", val)
}

In the above Golang code example we input a decimal integer value through the keyboard and then constructed a string from the numeric value input. At this point, the number is converted to a string. After that, we parsed the string as an integer of base-16. Finally, we used the Printf() function to output the value as a base-10 integer again.

How to Convert Between Numbers and Pointers in Go

Pointers are memory locations and they are also numbers, right? So, the logic would follow, they must be easily convertible and used as numbers. Old programming languages, like BCPL, actually treated pointers and numbers in a similar manner. Because of that, we could technically perform pointer arithmetic and some other strange stuff. Then, C separated the idea and made an explicit distinction between numbers and pointers, but still allowed some implicit conversion between pointers and integers. Therefore, it also allows some form of pointer arithmetic. Pointer arithmetic is actually popular among C programmers but it is unsafe. Now, Go has made a complete distinction between pointers and integers. However, conversion is still possible using unsafe packages. Here is an example of how to convert between numbers and pointers in Go:

package main

import (
	"fmt"
	"unsafe"
)

func main() {
	greet := "hello!"
	addrGreet := unsafe.Pointer(&greet)
	fmt.Printf("Address of greet is %d\n", addrGreet)
	addrGreetToStr := (*string)(addrGreet)
	fmt.Printf("pointer to string: %s\n", *addrGreetToStr)
	addr := uintptr(addrGreet)
	addr += 4 // This may cause panic. undefined behavior.
	str := (*string)(unsafe.Pointer(addr))
	fmt.Printf("String from pointer: %s\n", *str)
}

The above Golang code example converts the pointer – or the address of the string value (which, after all, is also a number) to string back and forth and tries to perform some arithmetic. The program executes fine, but at the point where we are doing pointer math, the program may panic and print some random values and will exit, finally, with a runtime error (at least in my case. It is harmless to try on your own if you would like).

The name of the package actually suggests that Go does not encourage implementing this kind of behavior. In fact, at the outset of the unsafe package documentation, it states: “Package unsafe contains operations that step around the type safety of Go programs. Packages that import unsafely may be non-portable and are not protected by the Go 1 compatibility guidelines.”

In Go, it is actually possible to disable use of unsafe operations by passing the flag -u to the Go compiler.

You can learn more about pointers in our tutorial: How to Use Pointers in Go.

Final Thoughts on Go Data Conversion

Conversion in Go is always a cautious affair. Loss of information, erratic or undefined behavior in conversions is not uncommon. However, programmers cannot completely do without conversion. We must use the standard way given by Go to perform any sort of conversion between data types. Nonetheless, Go has made it much safer to convert between data types – at least in comparison to its predecessors.

Read more Go and Golang programming tutorials.

Source: www.developer.com