What Is the `maps.Clone` Function in Go 1.21?

maps.Clone creates a shallow copy of a map in a single standard library call, returning nil if the source is nil and eliminating the need for manual iteration loops.

Introduced in Go 1.21, the maps.Clone function provides a standardized way to duplicate map headers without deep-copying the underlying key-value pairs. Prior to this addition, developers relied on boilerplate make and range loops to copy maps, leading to verbose and error-prone implementations. According to the JetBrains/go-modern-guidelines repository, adopting this helper clarifies intent while preserving critical nil semantics that manual implementations often accidentally destroy.

How maps.Clone Works

maps.Clone performs a shallow copy of the source map, allocating a new map header while referencing the same keys and values stored in the original.

  • Shallow semantics: Only the map structure is duplicated; keys and values are not recursively copied. For complex types like slices or pointers, the cloned map shares the same underlying data as the source.
  • Nil preservation: If the input map is nil, maps.Clone returns nil rather than an initialized empty map. This maintains type safety and prevents accidental allocations that change program logic.
  • Optimized implementation: The function uses the Go runtime's internal map iteration machinery, often outperforming hand-written loops by pre-allocating the appropriate capacity based on the source map's size.

Why Prefer maps.Clone Over Manual Copying

The go-modern-guidelines project documents several advantages of using the standard library helper instead of manual copying.

Clarity: A single function call expresses the operation's intent more clearly than a three-line initialization and iteration loop, improving readability for maintainers reviewing the code.

Safety: Manual implementations often accidentally convert nil maps into empty maps via make(), destroying the semantic distinction between an uninitialized map and an empty one. maps.Clone preserves this distinction by propagating nil values correctly.

Maintainability: Centralizing the copy logic in the standard library ensures that future optimizations or semantic changes to map copying are applied globally without requiring modifications to application code.

Performance: The runtime implementation leverages optimized memory allocation and iteration strategies that are difficult to replicate efficiently in user-space Go code.

Source Code Context

The rationale for using maps.Clone is formally defined in the repository's guideline files and feature documentation.

internal/guidelines/guidelines.json (lines 36-51): Contains the formal specification for the mapsclone rule, describing the transformation from manual loops to the standard library call and explaining the safety benefits regarding nil handling.

FEATURES.md (lines 35-55): Provides concrete before-and-after code comparisons and specifies the Go version requirement (1.21+), illustrating how the function eliminates boilerplate while maintaining correctness.

Practical Usage Examples

Migrating from Manual Copying (Pre-Go 1.21)

Before Go 1.21, copying a map required explicit allocation and iteration:

copied := make(map[string]int, len(src))
for k, v := range src {
    copied[k] = v
}

With Go 1.21 and later, the standard library simplifies this to a single call:

import "maps"

copied := maps.Clone(src)

Handling Nil Maps Safely

When working with potentially uninitialized maps, maps.Clone preserves the nil state rather than creating an empty map:

var src map[string]int // src is nil
clone := maps.Clone(src) // clone is also nil, not map[]

if clone == nil {
    // This branch executes, unlike with manual make()
}

Copying Maps with Struct Values

For maps containing structs, maps.Clone performs a shallow copy of the values. The struct values themselves are copied, but any pointer fields within them are shared:

type Person struct {
    Name string
    Age  int
}

original := map[string]Person{
    "alice": {"Alice", 30},
    "bob":   {"Bob", 25},
}

// Shallow copy – struct values are independent, but pointer fields would be shared
clone := maps.Clone(original)

Summary

  • maps.Clone is available in the standard library maps package starting with Go 1.21.
  • It creates a shallow copy of a map, duplicating only the header structure while sharing keys and values with the source.
  • Nil maps remain nil after cloning, avoiding accidental conversion to empty maps that occurs with make().
  • The implementation is optimized in the Go runtime and generally outperforms manual range loops.
  • The JetBrains/go-modern-guidelines repository recommends this function in internal/guidelines/guidelines.json to replace verbose copying boilerplate.

Frequently Asked Questions

What is the difference between maps.Clone and a manual copy loop?

maps.Clone is a single function call that handles allocation, iteration, and nil-checking automatically. A manual loop requires writing make(map[K]V, len(src)) followed by a for k, v := range src iteration, which is error-prone and obscures the programmer's intent. Additionally, manual implementations often accidentally allocate empty maps when the source is nil, whereas maps.Clone preserves nil semantics as documented in the repository's FEATURES.md.

Does maps.Clone perform a deep copy?

No, maps.Clone performs a shallow copy. It creates a new map header and copies references to the existing keys and values. If your map contains slices, maps, or pointers, the cloned map will reference the same underlying data structures. Deep copying requires implementing custom logic for your specific value types.

What happens if I clone a nil map?

maps.Clone returns nil when the input map is nil. This behavior differs from manually creating a map with make(), which produces an empty but initialized map. Preserving the nil state is crucial for APIs that distinguish between "unset" and "empty" map states, as emphasized in the guideline specification at internal/guidelines/guidelines.json.

When should I use maps.Clone instead of maps.Copy?

Use maps.Clone when you need to create a new, independent map containing all entries from the source. Use maps.Copy when you want to add entries from a source map into an existing destination map. maps.Clone handles allocation and nil-safety automatically, while maps.Copy requires you to initialize the destination map beforehand.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →