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 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 ArticleAI and machine learning for engineering design
    Next Article Agenton – AI Voice Agents for Automotive Dealerships

    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

    Five Ways to Lazy Load Images for Better Website Performance

    Development

    APPLE-SA-04-16-2025-3 tvOS 18.4.1

    Security

    Scattered Spider Behind Cyberattacks on M&S and Co-op, Causing Up to $592M in Damages

    Development

    Battlefield 6 devs plagued by “extraordinary stress and long hours” — changes to compete with Call of Duty, Fortnite are wrecking havoc, and I’m worried

    News & Updates

    Highlights

    CVE-2025-5891 – Unitech pm2 Regular Expression Complexity Vulnerability

    June 9, 2025

    CVE ID : CVE-2025-5891

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

    Description : A vulnerability classified as problematic was found in Unitech pm2 up to 6.0.6. This vulnerability affects unknown code of the file /lib/tools/Config.js. The manipulation leads to inefficient regular expression complexity. The attack can be initiated remotely. The exploit has been disclosed to the public and may be used.

    Severity: 4.3 | MEDIUM

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

    CVE-2025-47724 – Delta Electronics CNCSoft RCE

    June 4, 2025

    Can Good UX Protect Older Users From Digital Scams?

    June 25, 2025

    Higgs Audio

    August 9, 2025
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

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