Go语言中&T{}与new(T)创建对象指针的核心差异及功能对比
&T{} and new(T) in Go Great question! Let’s break down how these two approaches differ, and where one might be the only viable option:
First, the shared ground: both return a pointer to a newly allocated instance of T with all fields set to their zero values. Beyond that, their capabilities diverge significantly:
1. Initialization Flexibility (The Biggest Practical Difference)
&T{} lets you directly initialize specific struct fields at the time of allocation—this is its superpower. For example:
type Product struct { ID string Price float64 } // Create a pre-configured struct pointer in one line prodPtr := &Product{ID: "XYZ123", Price: 29.99}
In contrast, new(T) only gives you a pointer to a zero-valued T. You can’t pass any initialization parameters to it—you have to set fields separately after allocation:
prodPtr := new(Product) prodPtr.ID = "XYZ123" prodPtr.Price = 29.99
2. Supported Types
The new() built-in function works with any type in Go, including primitive types (like int, bool), pointers, and even functions. For example:
// Pointer to a zero-valued integer intPtr := new(int) // Pointer to a nil function funcPtr := new(func() error)
&T{}, however, is limited to composite types that support literal syntax—structs, arrays, slices, maps, and channels. You can’t write &int{} or &bool{} because primitive types don’t have an empty brace literal form.
3. Syntax and Intent
new(T)is an explicit allocation call, focused solely on creating a zero-valued instance and returning its pointer. It’s a holdover from lower-level languages but still useful for specific cases.&T{}is the more idiomatic Go approach for structs. It combines allocation and optional initialization in a single, readable line, making your intent clear: you’re creating a struct instance (possibly with custom values) and taking its address.
Cases Where One Works and the Other Doesn’t
Yes, there are exclusive use cases:
- Only
&T{}can initialize fields on creation: There’s no syntax to pass initial values tonew(T)—you have to set fields post-allocation. For one-liner pre-configured struct pointers,&T{}is your only option. - Only
new()works with primitive types: You can’t create a pointer to a primitive zero value using&{}syntax (e.g.,&int{}is invalid). For these scenarios,new(int)is the correct choice.
In most daily Go code, &T{} is preferred for structs due to its flexibility. new() is typically reserved for primitive types or when you explicitly want nothing but a zero-valued pointer.
内容的提问来源于stack exchange,提问作者Troskyvs

