The new() Function
Part of the Object Oriented Programming section of Coddy's GO journey — lesson 22 of 107.
Go provides a built-in function called new() that allocates memory for a type and returns a pointer to it. The allocated memory is initialized to the type's zero value.
p := new(int) // allocates memory for an int
fmt.Println(*p) // 0 (zero value)
fmt.Println(p) // 0xc000018030 (memory address)The new() function takes a type as its argument and returns a pointer to a newly allocated zero value of that type. This is particularly useful when you need a pointer but don't have an existing variable to reference.
With structs, new() creates a pointer to a struct with all fields set to their zero values.
type Person struct {
Name string
Age int
}
p := new(Person)
fmt.Println(p.Name) // "" (empty string)
fmt.Println(p.Age) // 0You might wonder when to use new() versus the address operator &. Both approaches below are equivalent:
// Using new()
p1 := new(Person)
// Using address operator with literal
p2 := &Person{}The &Person{} syntax is more common in practice because it allows you to initialize fields at the same time. Use new() when you specifically want a zero-valued instance and prefer explicit memory allocation semantics.
Challenge
EasyLet's build a configuration manager that demonstrates how new() allocates memory and initializes structs to their zero values. You'll see how this approach differs from using the address operator with a struct literal.
You'll organize your code across two files:
config.go: Define aServerConfigstruct withHost(string),Port(int),MaxConnections(int), andDebugMode(bool) fields. Create two functions:NewServerConfigthat usesnew()to allocate aServerConfigand returns the pointer directly (with all zero values)ConfigureServerthat takes a*ServerConfigpointer along with a host string and port integer, then sets those fields on the config through the pointer
Displaymethod on*ServerConfigthat returns a formatted string showing all configuration values.main.go: Read a host and port from input. First, create a config usingNewServerConfig()and display it to show the zero values. Then useConfigureServerto set the host and port, and display the config again to show the updated values.
The following inputs will be provided:
- Line 1: Host name (string)
- Line 2: Port number (integer)
Your Display method should return a string in this exact format:
Host: [Host]
Port: [Port]
MaxConnections: [MaxConnections]
DebugMode: [DebugMode]Print the display output twice—once before configuring (showing zero values) and once after configuring (showing the updated host and port).
For example, given localhost and 8080, your output should be:
Host:
Port: 0
MaxConnections: 0
DebugMode: false
Host: localhost
Port: 8080
MaxConnections: 0
DebugMode: falseNotice how the first display shows all zero values (empty string, 0, 0, false) because new() initializes everything to zero values. After calling ConfigureServer, only the host and port change while the other fields remain at their zero values.
Cheat sheet
The new() function allocates memory for a type and returns a pointer to it, initialized to the type's zero value:
p := new(int) // allocates memory for an int
fmt.Println(*p) // 0 (zero value)
fmt.Println(p) // 0xc000018030 (memory address)With structs, new() creates a pointer to a struct with all fields set to their zero values:
type Person struct {
Name string
Age int
}
p := new(Person)
fmt.Println(p.Name) // "" (empty string)
fmt.Println(p.Age) // 0Using new() versus the address operator & - both are equivalent:
// Using new()
p1 := new(Person)
// Using address operator with literal
p2 := &Person{}The &Person{} syntax is more common because it allows field initialization at creation time. Use new() when you want a zero-valued instance with explicit memory allocation semantics.
Try it yourself
package main
import (
"fmt"
)
func main() {
// Read input
var host string
var port int
fmt.Scanln(&host)
fmt.Scanln(&port)
// TODO: Create a config using NewServerConfig() and display it
// This will show the zero values
// TODO: Use ConfigureServer to set the host and port
// TODO: Display the config again to show updated values
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of Go OOP
External FilesGo Workspace & ModulesPackages & ImportsExported vs Unexported NamesIntroduction to OOP in GoStructs as ClassesDefining Methods on StructsPointer vs Value ReceiversStruct InitializationConstructor FunctionsRecap - Simple Calculator4Interfaces
Introduction to InterfacesImplicit ImplementationInterface as ContractEmpty Interface (any)Type AssertionType SwitchInterface CompositionStringer & Error InterfacesRecap - Shape Calculator7Encapsulation
Exported vs Unexported FieldsPackage-Level EncapsulationGetter & Setter MethodsInformation Hiding in GoRecap - Student Records10Generics (Go 1.18+)
Introduction to GenericsType ParametersType ConstraintsGeneric StructsGeneric Methods WorkaroundRecap - Generic Collection2Types & Structs Deep Dive
Basic & Composite TypesCustom Type DefinitionsStruct TagsAnonymous StructsNested StructsZero Values & DefaultsRecap - Contact Book5Composition Over Inheritance
Why Go Has No InheritanceStruct Embedding BasicsMethod PromotionEmbedding Multiple StructsEmbedding vs AggregationShadowing Embedded MethodsRecap - Employee Hierarchy8Error Handling & OOP
The error InterfaceCustom Error TypesError Wrapping (fmt.Errorf)Sentinel Errorserrors.Is() and errors.As()Panic, Defer, and RecoverRecap - File Parser3Pointers & Memory
Pointer Basics in GoPointers to StructsPass by Value vs ReferenceThe new() FunctionGarbage Collection in GoRecap - Linked List Builder6Polymorphism in Go
Polymorphism via InterfacesDuck Typing in GoInterface Satisfaction RulesPolymorphic CollectionsDependency InjectionRecap - Payment Processor9Concurrency & OOP
Goroutines BasicsChannels & CommunicationBuffered vs Unbuffered ChanSelect Statementsync.Mutex & sync.RWMutexsync.WaitGroupThread-Safe Struct DesignRecap - Worker Pool