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

      Development Release: KDE Linux 20250906

      September 6, 2025
      Recent

      Development Release: KDE Linux 20250906

      September 6, 2025

      Harnessing GitOps on Linux for Seamless, Git-First Infrastructure Management

      September 6, 2025

      How DevOps Teams Are Redefining Reliability with NixOS and OSTree-Powered Linux

      September 5, 2025
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»Development»What is New in Go 1.25? Explained with Examples

    What is New in Go 1.25? Explained with Examples

    September 7, 2025

    Go 1.25 isn’t a flashy release with big syntax changes. Instead, it’s a practical one: it fixes long-standing pitfalls, improves runtime safety, adds smarter tooling, and introduces a powerful new JSON engine. These are the kind of updates that make your day-to-day coding experience smoother and your production apps more reliable.

    Table of Contents

    • Table of Contents

    • Goodbye “Core Types”

    • Safer Nil-Pointer Handling

    • DWARF v5 Debug Info by Default

    • testing/synctest is Stable

    • Experimental encoding/json/v2

    • Tooling Improvements

    • Runtime Improvements

    • Flight Recorder API

    • Platform Updates

    • Key Takeaways

    • Sources

    Let’s walk through the highlights.

    Goodbye “Core Types”

    Core types were introduced in Go 1.18, where, according to the documentation, “a core type is an abstract construct that was introduced for expediency and to simplify dealing with generic operands”. For example, we have:

    • If a type is not a type parameter, its core type is simply its underlying type.

    • If the type is a type parameter, its core type exists only if all types in its type set share the same underlying type. In such cases, that common underlying type becomes the core type. Otherwise, no core type exists.

    In Go 1.25, the team removed the notion of core types from the spec and instead defined each feature with explicit rules for generics, simplifying the language while keeping everything fully backward-compatible. For example, operations like addition on a generic type are now described directly in terms of type sets, without needing to reference core types.

    Safer Nil-Pointer Handling

    A bug introduced in Go 1.21 sometimes prevented nil pointer panics from triggering. That’s now fixed. If you dereference a nil, it will reliably panic. Previously, the behavior was:

    <span class="hljs-keyword">package</span> main
    
    <span class="hljs-keyword">import</span> (
        <span class="hljs-string">"fmt"</span>
        <span class="hljs-string">"os"</span>
    )
    
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
        <span class="hljs-comment">// Try to open a file that doesn't exist.</span>
        <span class="hljs-comment">// os.Open returns a nil file handle and a non-nil error.</span>
        f, err := os.Open(<span class="hljs-string">"does-not-exist.txt"</span>) <span class="hljs-comment">// f is nil, err is non-nil</span>
        fmt.Println(<span class="hljs-string">"err:"</span>, err) <span class="hljs-comment">// Prints the error</span>
    
        <span class="hljs-comment">// Buggy behavior explanation:</span>
        <span class="hljs-comment">// The program uses f.Name() before checking the error.</span>
        <span class="hljs-comment">// Since f is nil, this call panics at runtime.</span>
        <span class="hljs-comment">// Older Go versions (1.21–1.24) sometimes let this run,</span>
        fmt.Println(<span class="hljs-string">"name:"</span>, f.Name())
    }
    

    In Go 1.21–1.24, a compiler bug sometimes suppressed the panic in the code above and made it look like your program was “fine.” In Go 1.25, it will no longer run successfully. With the fixed behavior, we have:

    <span class="hljs-keyword">package</span> main
    
    <span class="hljs-keyword">import</span> (
        <span class="hljs-string">"fmt"</span>
        <span class="hljs-string">"os"</span>
    )
    
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
        <span class="hljs-comment">// Try to open a file that doesn't exist.</span>
        <span class="hljs-comment">// os.Open returns a nil file handle and a non-nil error.</span>
        f, err := os.Open(<span class="hljs-string">"does-not-exist.txt"</span>) 
        fmt.Println(<span class="hljs-string">"err:"</span>, err) <span class="hljs-comment">// Prints an error</span>
    
        <span class="hljs-comment">// This now reliably panics, since f is nil and you’re dereferencing it.</span>
        fmt.Println(<span class="hljs-string">"name:"</span>, f.Name())
    }
    

    The key difference is that it now throws a panic, making the behavior more predictable.

    DWARF v5 Debug Info by Default

    DWARF is a standardized format for storing debugging information inside compiled binaries.
    Think of it as a map that tells debuggers (like gdb, dlv for Go, or IDEs like VS Code/GoLand) how your compiled program relates back to your source code.

    Go 1.25 now uses DWARF v5 for debug information. The result is smaller binaries and faster linking. If you need older tooling compatibility, you can disable it with GOEXPERIMENT=nodwarf5.

    <span class="hljs-comment"># Normal build (DWARF v5 enabled automatically):</span>
    go build ./...
    
    <span class="hljs-comment"># If you have tooling that doesn’t support DWARF v5, you can disable it:</span>
    GOEXPERIMENT=nodwarf5 go build ./...
    

    testing/synctest is Stable

    Testing concurrent code just got easier. The new testing/synctest package lets you run concurrency tests in a controlled environment where goroutines and time are deterministic.

    <span class="hljs-comment">// Run with: go test</span>
    <span class="hljs-keyword">package</span> counter
    
    <span class="hljs-keyword">import</span> (
        <span class="hljs-string">"testing"</span>
        <span class="hljs-string">"testing/synctest"</span>
    )
    
    <span class="hljs-comment">// Counter is a simple struct holding an integer.</span>
    <span class="hljs-comment">// It has methods to increment the count and retrieve the value.</span>
    <span class="hljs-keyword">type</span> Counter <span class="hljs-keyword">struct</span>{ n <span class="hljs-keyword">int</span> }
    
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(c *Counter)</span> <span class="hljs-title">Inc</span><span class="hljs-params">()</span></span> { c.n++ } <span class="hljs-comment">// Increase counter by 1</span>
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(c *Counter)</span> <span class="hljs-title">N</span><span class="hljs-params">()</span> <span class="hljs-title">int</span></span> { <span class="hljs-keyword">return</span> c.n } <span class="hljs-comment">// Return the current count</span>
    
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">TestCounter_Inc_Deterministic</span><span class="hljs-params">(t *testing.T)</span></span> {
        <span class="hljs-comment">// synctest.New creates a special deterministic test environment ("bubble").</span>
        <span class="hljs-comment">// Inside this bubble, goroutines are scheduled in a controlled way,</span>
        <span class="hljs-comment">// so the test result is always predictable (no race conditions).</span>
        st := synctest.New()
        <span class="hljs-keyword">defer</span> st.Done() <span class="hljs-comment">// Cleanup: always close the test bubble at the end.</span>
    
        c := &Counter{}
        <span class="hljs-keyword">const</span> workers = <span class="hljs-number">10</span>
    
        <span class="hljs-comment">// Start 10 goroutines inside the synctest bubble.</span>
        <span class="hljs-comment">// Each goroutine calls c.Inc(), incrementing the counter.</span>
        <span class="hljs-keyword">for</span> i := <span class="hljs-number">0</span>; i < workers; i++ {
            st.Go(<span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">()</span></span> { c.Inc() })
        }
    
        <span class="hljs-comment">// Run the bubble until all goroutines are finished.</span>
        <span class="hljs-comment">// This ensures deterministic completion of the test.</span>
        st.Run()
    
        <span class="hljs-comment">// Verify the result: counter should equal number of goroutines (10).</span>
        <span class="hljs-comment">// If not, fail the test with a clear message.</span>
        <span class="hljs-keyword">if</span> got, want := c.N(), workers; got != want {
            t.Fatalf(<span class="hljs-string">"got %d, want %d"</span>, got, want)
        }
    }
    

    With the new testing/synctest, tests ensure a deterministic, flake-free run, so the counter always ends up at 10.

    Experimental encoding/json/v2

    A brand-new JSON engine is available under the GOEXPERIMENT=jsonv2 flag. It’s faster, more efficient, and includes a streaming-friendly jsontext package. Even better, the old encoding/json can piggyback on the new engine—so you get performance boosts without breaking old code.

    Tooling Improvements

    • go vet now catches common mistakes like incorrect sync.WaitGroup.Add usage and unsafe host:port handling.

    • go doc -http serves documentation locally in your browser.

    • go build -asan can detect memory leaks automatically.

    These small upgrades add up to a smoother dev workflow.

    Runtime Improvements

    Go now runs smarter inside containers. On Linux, it automatically detects how many CPUs the container is allowed to use and adjusts itself. There’s also a new experimental garbage collector called greenteagc, which can make memory cleanup up to 40% faster in some cases.

    Flight Recorder API

    Have you ever wished you could see exactly what your Go application was doing when something went wrong—like when a request suddenly takes 10 seconds instead of 100 milliseconds, or your app mysteriously starts using too much CPU? By the time you notice, it’s usually too late to debug because the issue has already passed. Go’s new FlightRecorder feature solves this by continuously capturing a lightweight runtime trace in memory, allowing your program to snapshot the last few seconds of activity to a file whenever a significant event occurs.

    Platform Updates

    • macOS 12 (Monterey) is now the minimum supported version.

    • Windows/ARM 32-bit support is deprecated and will be removed in Go 1.26.

    • RISC-V and Loong64 gained new capabilities like plugin builds and race detection.

    Key Takeaways

    • Safer by default: no more silent nil pointer bugs, better panic reporting.

    • Faster builds & runtime: DWARF v5 debug info, container-aware scheduling, and optional GC improvements.

    • Better tooling: smarter go vet, memory-leak detection, local docs.

    • Modern JSON: encoding/json/v2 is the future, with huge performance gains.

    Go 1.25 brings meaningful improvements across performance, correctness, and developer experience. From smarter CPU usage in containers to reduced garbage collector overhead, from more predictable runtime behavior to new tools like FlightRecorder, this release shows Go’s commitment to staying simple while evolving with modern workloads. If you haven’t tried it yet, now’s the time—upgrade, experiment with the new features, and see how they can make your applications faster, safer, and easier to debug.

    Sources

    https://go.dev/doc/go1.25

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

    Facebook Twitter Reddit Email Copy Link
    Previous ArticleScaling Up Reinforcement Learning for Traffic Smoothing: A 100-AV Highway Deployment

    Related Posts

    Artificial Intelligence

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

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

    Repurposing Protein Folding Models for Generation with Latent Diffusion

    September 7, 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

    Kong AI Gateway 3.11 introduces new method for reducing token costs

    Tech & Work

    Amazon just confirmed its July Prime Day sale will be back, despite looming tariffs

    News & Updates

    Windows Snipping Tool Gets Smarter with New Text Extractor feature in Upcoming Update

    Operating Systems

    Microsoft wants you to chat with its browser now – but can you trust this Copilot?

    News & Updates

    Highlights

    CVE-2025-49850 – Apache PRJ File Heap Buffer Overflow

    June 17, 2025

    CVE ID : CVE-2025-49850

    Published : June 17, 2025, 7:15 p.m. | 1 hour, 15 minutes ago

    Description : A Heap-based Buffer Overflow vulnerability exists within the parsing of PRJ files. The issues result from the lack of proper validation of user-supplied data, which can result in different memory corruption issues within the application, such as reading and writing past the end of allocated data structures.

    Severity: 0.0 | NA

    Visit the link for more details, such as CVSS details, affected products, timeline, and more…

    “In Array Keys” Validation Rule Added in Laravel 12.16

    May 29, 2025

    Breaking Down Apple’s Liquid Glass: The Tech, The Hype, and The Reality

    June 11, 2025

    CVE-2025-3628 – Moodle Anonymous Assignment De-Anonymization Vulnerability

    April 25, 2025
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

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