Constructor Patterns
In this page:
func NewName(param type) *Name {
return &Name{Field: param}
}
A Basic Constructor Function
Since Go has no constructor keyword, the idiomatic pattern is a plain function, usually named NewType, that builds a struct value (often with some setup logic) and returns it.
Example: A Basic Constructor Function
// Every Go file belongs to a package; main builds an executable
package main
// Import the fmt package
import "fmt"
// Define a struct type named Person
type Person struct {
Name string
Age int
}
// Define the function NewPerson
func NewPerson(name string, age int) Person {
// Send Person{Name: name, Age: age} back to the caller
return Person{Name: name, Age: age}
}
// main is where the program starts running
func main() {
// Short declaration: create p and infer the type
p := NewPerson("Divya", 27)
// Print the values followed by a newline
fmt.Println(p)
}
Login to try C/C++/Java/PHP code in the editor
Validating Input in a Constructor
A constructor function is a natural place to validate arguments and return an error if they're invalid, keeping bad data from ever forming a struct in the first place.
Example: Validating Input in a Constructor
// Every Go file belongs to a package; main builds an executable
package main
// Import the packages this program uses
import (
"errors"
"fmt"
)
// Define a struct type named Account
type Account struct {
Balance float64
}
// Define the function NewAccount
func NewAccount(initial float64) (*Account, error) {
// Check whether initial < 0
if initial < 0 {
return nil, errors.New("initial balance cannot be negative")
}
return &Account{Balance: initial}, nil
}
// main is where the program starts running
func main() {
// Short declaration: create acc, err and infer the type
acc, err := NewAccount(100)
// Print the values followed by a newline
fmt.Println(acc, err)
}
Login to try C/C++/Java/PHP code in the editor
Returning a Pointer from a Constructor
When a type has pointer-receiver methods, it's common for its constructor to return a *Type directly, so the value is immediately ready to be mutated through those methods without extra addressing.
Example: Returning a Pointer from a Constructor
// Every Go file belongs to a package; main builds an executable
package main
// Import the fmt package
import "fmt"
// Define a struct type named Counter
type Counter struct {
value int
}
// Define the function NewCounter
func NewCounter() *Counter {
// Send &Counter{value: 0} back to the caller
return &Counter{value: 0}
}
// Define the method Increment on type Counter
func (c *Counter) Increment() {
c.value++
}
// main is where the program starts running
func main() {
// Short declaration: create c and infer the type
c := NewCounter()
c.Increment()
c.Increment()
fmt.Println(c.value)
}
Login to try C/C++/Java/PHP code in the editor
- Expecting a special constructor syntax like other languages -- Go just uses ordinary functions, conventionally named NewXxx.
- Exporting all struct fields when a constructor is meant to enforce invariants, allowing callers to bypass validation by setting fields directly.
- Returning a struct value from a NewXxx function when a pointer was intended, causing inconsistency with the type's other pointer-receiver methods.
- Go has no dedicated constructor syntax -- a plain function conventionally named NewType builds and returns a value.
- Constructor functions can validate inputs and set sensible defaults before returning the struct.
- Returning a pointer (*Type) from a constructor is common when the type has pointer-receiver methods.
- Unexported fields combined with a constructor function enforce that objects are only created through valid initial states.
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: