Type casting is the conversion of variables or data from one data type to another. In most cases, a variable of any type can be converted to another, but that does not guarantee that the data will be intact or preserved. In the previous tutorial, we have talked about how to use methods in Golang. In this tutorial, we will walk through type casting in Go, its uses, and practical examples of type casting.
In order to follow through this article:-
- You need to have a basic understanding of programming.
- You need to download the Go compiler from the official website and follow the directions to install it based on your operating system being either Windows, MacOS or any of the Linux distributions.
- You need a code editor like visual studio, atom or sublime text. Alternatively, you can download an Integrated Development Environment (IDE). An IDE is an improved code editor with added qualities customized to help you write and execute codes easier. Goland is the most popular IDE used for developing Go programs.
- You need to have an understanding of Go basic data types and aggregate types like structs and arrays.
Introduction to Type Casting in Golang [Explained with examples]
Type casting involves converting variables between data types. In Go, there is no official term as type casting, instead it is called Type Conversion. In other languages like C and C++, the compiler can perform automatic type casting, but Go doesn’t allow that because of its robust type system.
The general syntax for converting between types in Go is:-
The format above converts type_expression in a known type to the type specified by Type_name.
Type Casting between Integer types
Go contains a number of built-in integer types. Variables of these integer types can be converted between each other using the general syntax of type conversion.
When converting from a larger integer type to a smaller type, you have to ensure that no information will be lost after conversion. Each integer type has a range of values it can store, therefore converting a value to a type with a lower range will result in an overflow.
In the snippet above, we declared an int16 variable, val1 and initialized it to 130. We then declared an int8 variable val2 and cast the value of val1 into val2 on line 12. An int8 value cannot store the number 130, therefore 130 from val1 will overflow into val2. This means that the difference of which 130 is greater than the maximum value of int8 is added to the minimum value of int8.
You may declare a new data type where the underlying type is an integer type. Go allows you to convert between variables of compatible underlying data types.
Type Casting between Floating Point Types
Go allows you to easily cast a variable’s data type from float32 to float64 and vice versa using the general type conversion syntax. It is not advised to cast between both float values in code because it could introduce indefinite values within your code.
Type Casting between Integer and Float Types
When converting a variable from an integer type to a float type, the data remains intact . But when converting from a float type to an integer type, the digits after the decimal point are truncated.
Type Casting for Strings
A string data can easily be cast into a slice of bytes. This allows a byte in the string to be changeable. Let's show a practical example of applying this technique.
The snippet above is an inefficient program that converts each ‘l’ character in a string into a question mark (?). In lines 12 and 19, we cast a string (str1) into a slice of byte and back to a string (str2) respectively. A string is an immutable data type, but after converting it to a slice of bytes, we were able to change some of its characters and convert back to a string.
A byte can also be easily cast into a rune. A byte is an alias for uint8 and a rune is an alias for uint32, therefore we can cast them to each other since their underlying types can be cast to each other.
Application of Type Casting
Binary operations like arithmetic operations (addition, subtraction, division, module etc) and logical operations ( less than, greater than, etc) can only be performed between two variables of the same data type. In an algorithm where you’ll need to perform a binary operation between two variables of different types, we cast one of the types to the other to prevent a compiler error.
Also, when passing an argument into a function call, we can cast the current value to the type needed if it is inevitably in another compatible type. The same principle applies when returning a value from a function. Let’s see an example of a function that converts a value in a certain base to base 10.
In the function above, there are four cases of type casting which are:-
- On line 17, we cast currentNum which is currently of type int64 to int8 so it can be compared using a logical operator to
- On line 24, the function Pow takes two arguments of type float64, we cast base and index of types int8 and int64 to float64.
- On line 28, we cast currentNum also to float64 so it can be multiplied with powerValue of type float64.
- On line 32, we cast answer to type int64 so it can be returned from the function convertNumToBase10 which returns an int64
Less type casting within a program improves code readability and organization. The function above can ultimately be improved to include less type casting. The application of typecasting described above also applies to operations involving strings and a slice of bytes.
Type Casting for Structs
We can use the general type casting syntax to convert between two structs with the same number of fields, field names and field types.
Type Casting for Functions
We can cast between two functions if they have the same signature. A typical example where this is applied is when creating a web server using the inbuilt net/http package. Let's show an example of how this works below.
The snippet above is a http server with a single handler that returns “Hello World”. Between lines 8 to 10, we declare a function which has the same signature as a typical http handler. On line 13, we then cast helloHandler to the builtin type, http.HandlerFunc which has the same function signature as helloHandler. The definition of http.HandlerFunc in the builtin net/http package is shown below.
Go's strongly typed system means that you'll need to embrace type casting to write efficient programs in many cases. Knowing how well to manage types and write efficient type casting will help you manage bugs and write more efficient software's.