Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      This week in AI updates: Mistral’s new Le Chat features, ChatGPT updates, and more (September 5, 2025)

      September 6, 2025

      Designing For TV: Principles, Patterns And Practical Guidance (Part 2)

      September 5, 2025

      Neo4j introduces new graph architecture that allows operational and analytics workloads to be run together

      September 5, 2025

      Beyond the benchmarks: Understanding the coding personalities of different LLMs

      September 5, 2025

      Development Release: KDE Linux 20250906

      September 6, 2025

      Hitachi Energy Pledges $1B to Strengthen US Grid, Build Largest Transformer Plant in Virginia

      September 5, 2025

      How to debug a web app with Playwright MCP and GitHub Copilot

      September 5, 2025

      Between Strategy and Story: Thierry Chopain’s Creative Path

      September 5, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      Health Monitoring Android App using SQLite

      September 7, 2025
      Recent

      Health Monitoring Android App using SQLite

      September 7, 2025

      Convertedbook – Live LaTeX Preview in the Browser

      September 7, 2025

      Why browsers throttle JavaScript timers (and what to do about it)

      September 6, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured

      Speed Isn’t Everything When Buying SSDs – Here’s What Really Matters!

      September 8, 2025
      Recent

      Speed Isn’t Everything When Buying SSDs – Here’s What Really Matters!

      September 8, 2025

      14 Themes for Beautifying Your Ghostty Terminal

      September 8, 2025

      Development Release: KDE Linux 20250906

      September 6, 2025
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»Development»What is Typecasting in Go? Explained with Code Examples

    What is Typecasting in Go? Explained with Code Examples

    April 22, 2025

    When you’re working with data in Go, especially when you need to handle dynamic inputs like JSON from third-party APIs, understanding how to properly convert between data types is key. This helps you avoid bugs and crashes.

    Often times, the values returned by APIs are stored as generic interface{} types. These require explicit typecasting to use them correctly. But without proper type conversion, you risk data loss, unexpected behavior, or even runtime crashes.

    In this article, we’ll explore how typecasting works in Go. You’ll learn what it is, how to do it correctly, and why it’s crucial for writing safe and reliable code.

    You’ll learn about implicit vs explicit typecasting, common pitfalls to avoid, and how to safely work with dynamic data. We’ll also cover practical examples, including how to handle JSON data and how Go’s new generics feature can simplify type conversions.

    Table of Contents:

    • Why You Should Care About Typecasting

    • What Is Typecasting?

    • How to Typecast in Go

    • Common Mistakes to Avoid

    • A Real-World Example: Where Things Go Wrong

    • Advanced: How to Use Generics for Safer Typecasting

    • Final Thoughts

    • Common Type Conversion Table in Go

    • Helpful Packages for Type Conversion

    • References

    Why You Should Care About Typecasting

    I decided to write about this after running into a real issue in a company’s codebase. The app was pulling data from a third-party API that returned JSON objects. The values were dynamic and stored as generic interface{} types, but the code was trying to use them directly as int, float64, and string without checking or converting the types properly. This caused silent bugs, unexpected behavior, and even crashes that took hours to trace back.

    If you’re learning Go – or any language – knowing when and how to typecast can save hours of debugging. So let’s get into it.

    What Is Typecasting?

    Typecasting (or type conversion) is when you convert one type of variable into another. For example, turning an int into a float, or a string into a number. It’s a simple but essential technique for working with data that doesn’t always come in the type you expect.

    There are two main types of typecasting:

    • Implicit (automatic): Happens behind the scenes, usually when it’s safe (for example, int to float64 in some languages).

    • Explicit (manual): You, the developer, are in charge of the conversion. This is the case in Go.

    Why does this matter? Because if you don’t convert types correctly, your program might:

    • Lose data (for example, decimals getting cut off).

    • Crash unexpectedly.

    • Show incorrect results to users.

    I share some resources at the end of the article if you’re looking for Go packages that simplify type conversions and reduce boilerplate.

    How to Typecast in Go

    Go is a statically typed language, and it doesn’t do implicit conversions between different types. If you want to change a type, you have to do it yourself using explicit syntax.

    Let’s look at some basic examples:

    <span class="hljs-keyword">var</span> a <span class="hljs-keyword">int</span> = <span class="hljs-number">42</span>                     <span class="hljs-comment">// Declare a variable 'a' of type int and assign the value 42</span>
    <span class="hljs-keyword">var</span> b <span class="hljs-keyword">float64</span> = <span class="hljs-keyword">float64</span>(a)        <span class="hljs-comment">// Explicitly convert 'a' from int to float64 and store it in 'b'</span>
                                      <span class="hljs-comment">// Go requires manual (explicit) type conversion between different types</span>
    

    Here, we’re converting an int (a) into a float64 (b). This is a widening conversion – it’s safe because every integer can be represented as a float.

    Now the reverse:

    <span class="hljs-keyword">var</span> x <span class="hljs-keyword">float64</span> = <span class="hljs-number">9.8</span>              <span class="hljs-comment">// Declare a float64 variable 'x' with a decimal value</span>
    <span class="hljs-keyword">var</span> y <span class="hljs-keyword">int</span> = <span class="hljs-keyword">int</span>(x)               <span class="hljs-comment">// Convert 'x' to an int and store it in 'y'</span>
                                     <span class="hljs-comment">// This removes (truncates) everything after the decimal point</span>
                                     <span class="hljs-comment">// So y will be 9, not 10 — it doesn't round!</span>
    

    Here, we convert a float64 to an int, which truncates the decimal part. This is a narrowing conversion and can lead to data loss.

    Go forces you to be explicit so you don’t accidentally lose information or break your logic.

    Common Mistakes to Avoid

    When working with dynamic data like JSON or third-party APIs, it’s common to use interface{} to represent unknown types. But you can’t directly use them as specific types without checking first.

    Here’s a mistake many beginners make:

    <span class="hljs-keyword">var</span> data <span class="hljs-keyword">interface</span>{} = <span class="hljs-string">"123"</span>       <span class="hljs-comment">// 'data' holds a value of type interface{} (a generic type)</span>
    value := data.(<span class="hljs-keyword">string</span>)             <span class="hljs-comment">// This tries to assert that 'data' is a string</span>
                                       <span class="hljs-comment">// If it's not a string, this will panic and crash the program</span>
    

    If data isn’t actually a string, this will panic at runtime.

    A safer version would be:

    value, ok := data.(<span class="hljs-keyword">string</span>)         <span class="hljs-comment">// Try to convert 'data' to string, safely</span>
    <span class="hljs-keyword">if</span> !ok {
        fmt.Println(<span class="hljs-string">"Type assertion failed"</span>)  <span class="hljs-comment">// If the type doesn't match, 'ok' will be false</span>
    } <span class="hljs-keyword">else</span> {
        fmt.Println(<span class="hljs-string">"Value is:"</span>, value)       <span class="hljs-comment">// Only use 'value' if assertion was successful</span>
    }
    

    This checks the type before converting and avoids a crash. Always handle the ok case when asserting types from interface{}.

    A Real-World Example: Where Things Go Wrong

    We will be using a lot of the JSON marshal and unmarshal functions. If you want to understand what these are, here’s a quick introduction or review.

    What is Marshaling in Go?

    Marshaling refers to the process of converting Go data structures into a JSON representation. This is especially useful when you’re preparing data to be sent over the network or saved to a file. The result of marshaling is typically a byte slice containing the JSON string.

    Unmarshaling, on the other hand, is the reverse operation. It converts JSON data into Go structures, allowing you to work with external or dynamic data formats in a strongly typed manner.

    In typical applications, you might marshal a struct to send data via an API, or unmarshal a JSON payload received from a third-party service.

    When using structs, marshalling and unmarshalling are straightforward and benefit from field tags that guide JSON key mapping. But when working with unstructured or unknown JSON formats, you might unmarshal into a map[string]interface{}. In these cases, type assertions become necessary to safely access and manipulate the data.

    Understanding how marshalling and unmarshalling work is fundamental when building services that consume or expose APIs, interact with webhooks, or deal with configuration files in JSON format.

    Alright, now back to our example:

    Let’s say you get a JSON response from an API and unmarshal it into a map:

    <span class="hljs-keyword">package</span> main
    
    <span class="hljs-keyword">import</span> (
        <span class="hljs-string">"encoding/json"</span>
        <span class="hljs-string">"fmt"</span>
    )
    
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
        data := []<span class="hljs-keyword">byte</span>(<span class="hljs-string">`{"price": 10.99}`</span>)        <span class="hljs-comment">// Simulated JSON input</span>
    
        <span class="hljs-keyword">var</span> result <span class="hljs-keyword">map</span>[<span class="hljs-keyword">string</span>]<span class="hljs-keyword">interface</span>{}         <span class="hljs-comment">// Use a map to unmarshal the JSON</span>
        json.Unmarshal(data, &result)             <span class="hljs-comment">// Unmarshal into a generic map</span>
    
        price := result[<span class="hljs-string">"price"</span>].(<span class="hljs-keyword">float64</span>)        <span class="hljs-comment">// Correctly assert that price is a float64</span>
        fmt.Println(<span class="hljs-string">"The price is:"</span>, price)
    
        total := <span class="hljs-keyword">int</span>(result[<span class="hljs-string">"price"</span>])             <span class="hljs-comment">// ❌ This will fail!</span>
    }
    

    This fails because result["price"] is of type interface{}. Trying to convert it directly to int causes a compile-time error:

    cannot convert result[“price”] (map index expression of type interface{}) to type int: need type assertion

    You need to assert the type first.

    The Right Way to Do It

    Here’s the safe and correct version:

    <span class="hljs-keyword">package</span> main
    
    <span class="hljs-keyword">import</span> (
        <span class="hljs-string">"encoding/json"</span>
        <span class="hljs-string">"fmt"</span>
    )
    
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
        data := []<span class="hljs-keyword">byte</span>(<span class="hljs-string">`{"price": 10.99}`</span>)        <span class="hljs-comment">// JSON input representing a float value</span>
    
        <span class="hljs-keyword">var</span> result <span class="hljs-keyword">map</span>[<span class="hljs-keyword">string</span>]<span class="hljs-keyword">interface</span>{}         <span class="hljs-comment">// Create a map to hold the parsed JSON</span>
        json.Unmarshal(data, &result)             <span class="hljs-comment">// Parse the JSON into the map</span>
    
        <span class="hljs-comment">// Step 1: Assert that the value is a float64</span>
        priceFloat, ok := result[<span class="hljs-string">"price"</span>].(<span class="hljs-keyword">float64</span>)
        <span class="hljs-keyword">if</span> !ok {
            fmt.Println(<span class="hljs-string">"Failed to convert price to float64"</span>)
            <span class="hljs-keyword">return</span>
        }
    
        fmt.Println(<span class="hljs-string">"Total as float:"</span>, priceFloat)  <span class="hljs-comment">// Successfully extracted float value</span>
    
        <span class="hljs-comment">// Step 2: Convert the float to an int (truncates decimals)</span>
        total := <span class="hljs-keyword">int</span>(priceFloat)
        fmt.Println(<span class="hljs-string">"Total as integer:"</span>, total)     <span class="hljs-comment">// Final integer result (e.g., 10 from 10.99)</span>
    }
    

    This works because we first check that the value is a float64 and only then convert it to an int. That two-step process – type assertion then conversion – is key to avoiding errors.

    Advanced: How to Use Generics for Safer Typecasting

    With the introduction of generics in Go 1.18, you can write reusable functions that work with any type. Generics let you define functions where the type can be specified when the function is called.

    What are Generics in Go?

    Generics were introduced in Go 1.18 to allow writing functions and data structures that work with any type. They help reduce code duplication and increase type safety by enabling parameterized types.

    In the context of typecasting, generics allow you to write flexible helpers (like getValue[T]) that reduce repetitive interface{} assertions and make your code easier to maintain.

    • Type parameters are defined with square brackets: [T any]

    • The any keyword is an alias for interface{}

    • Compile-time checks ensure the past types are used safely

    Generics are especially useful in libraries, APIs, and when working with dynamic structures like JSON objects.

    Let’s say you want to extract values from map[string]interface{} without writing repetitive assertions:

    <span class="hljs-comment">// A generic function that safely retrieves and type-asserts a value from a map</span>
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">getValue</span>[<span class="hljs-title">T</span> <span class="hljs-title">any</span>]<span class="hljs-params">(data <span class="hljs-keyword">map</span>[<span class="hljs-keyword">string</span>]<span class="hljs-keyword">interface</span>{}, key <span class="hljs-keyword">string</span>)</span> <span class="hljs-params">(T, <span class="hljs-keyword">bool</span>)</span></span> {
        val, ok := data[key]                  <span class="hljs-comment">// Check if the key exists in the map</span>
        <span class="hljs-keyword">if</span> !ok {
            <span class="hljs-keyword">var</span> zero T                        <span class="hljs-comment">// Declare a zero value of type T</span>
            <span class="hljs-keyword">return</span> zero, <span class="hljs-literal">false</span>                <span class="hljs-comment">// Return zero value and false if key not found</span>
        }
    
        converted, ok := val.(T)              <span class="hljs-comment">// Try to convert (type assert) the value to type T</span>
        <span class="hljs-keyword">return</span> converted, ok                  <span class="hljs-comment">// Return the result and success status</span>
    }
    

    This function:

    • Accepts any type T that you specify (like float64, string, and so on)

    • Asserts the type for you

    • Returns the value and a boolean indicating success

    Usage:

    price, ok := getValue[<span class="hljs-keyword">float64</span>](result, <span class="hljs-string">"price"</span>) <span class="hljs-comment">// Try to get a float64 from the map</span>
    <span class="hljs-keyword">if</span> !ok {
        fmt.Println(<span class="hljs-string">"Price not found or wrong type"</span>)
    }
    
    title, ok := getValue[<span class="hljs-keyword">string</span>](result, <span class="hljs-string">"title"</span>)  <span class="hljs-comment">// Try to get a string from the map</span>
    <span class="hljs-keyword">if</span> !ok {
        fmt.Println(<span class="hljs-string">"Title not found or wrong type"</span>)
    }
    

    This pattern keeps your code clean and readable while avoiding panics from unsafe assertions.

    Final Thoughts

    Whether you’re just starting with Go or diving into more advanced patterns like generics, understanding typecasting is key to writing safe and reliable code.

    It may seem like a small detail, but incorrect type conversions can cause crashes, bugs, or silent data loss – especially when working with JSON, APIs, or user input.

    Here’s what you should take away:

    • 🧠 Always know the type you’re working with.

    • 🔍 Use type assertions carefully and check the ok value.

    • 🧰 Use generics to simplify repetitive assertion logic.

    • 💡 Don’t rely on luck — be intentional with conversions.

    Mastering typecasting in Go will not only make you a better developer but also help you understand how typed systems work across different languages.

    Common Type Conversion Table in Go

    From TypeTo TypeSyntax ExampleNotes
    intfloat64float64(myInt)Safe, widening conversion
    float64intint(myFloat)Truncates decimals
    stringintstrconv.Atoi(myString)Returns int and error
    intstringstrconv.Itoa(myInt)Converts int to decimal string
    []bytestringstring(myBytes)Valid UTF-8 required
    string[]byte[]byte(myString)Creates byte slice

    Helpful Packages for Type Conversion

    • strconv: Converting strings to numbers and vice versa

    • reflect: Introspect types at runtime (use with caution)

    • encoding/json: Automatic type mapping when unmarshaling

    • fmt: Quick conversion to string with formatting

    References

    • https://go.dev/doc/effective_go

    • https://go.dev/doc/tutorial/generics

    • Golang Cast: Go Type Casting and Type Conversion

    Source: freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More 

    Facebook Twitter Reddit Email Copy Link
    Previous ArticleEssential Machine Learning Concepts Animated
    Next Article How to Use a Foreign Key in Django

    Related Posts

    Artificial Intelligence

    Scaling Up Reinforcement Learning for Traffic Smoothing: A 100-AV Highway Deployment

    September 8, 2025
    Repurposing Protein Folding Models for Generation with Latent Diffusion
    Artificial Intelligence

    Repurposing Protein Folding Models for Generation with Latent Diffusion

    September 8, 2025
    Leave A Reply Cancel Reply

    For security, use of Google's reCAPTCHA service is required which is subject to the Google Privacy Policy and Terms of Use.

    Continue Reading

    CVE-2025-6693 – RT-Thread Device Memory Corruption Vulnerability

    Common Vulnerabilities and Exposures (CVEs)

    We Might Need Something Between Root and Relative CSS Units for “Base Elements”

    News & Updates

    PUBLOAD and Pubshell Malware Used in Mustang Panda’s Tibet-Specific Attack

    Development

    Tips for Hosting Your Client’s WordPress Website

    Learning Resources

    Highlights

    GPT-4.1 is here, but not for everyone. Here’s who can try the new models

    April 14, 2025

    OpenAI just launched a new family of models. Meet GPT-4.1, GPT-4.1 mini, and GPT-4.1 nano.…

    Get a Google Pixel 9a and Pixel Buds A-Series on T-Mobile – here’s how it works

    June 11, 2025

    Stream multi-channel audio to Amazon Transcribe using the Web Audio API

    June 9, 2025

    Windows User Count Controversy: Microsoft Silently “Corrects” User Base to 1.4 Billion After Implied 400M Drop

    July 2, 2025
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.