Introduction to golang constructor
Go by design is not an Object Oriented Programming language (OOP) like Java and Python. This means that Go does not offer constructors natively like Java and Python does. The idiomatic way for setting up a new data structure using constructors is to use proper zero values coupled with factory function.
To construct a decimal degrees location from degrees, minutes, and seconds, you can use the decimal method with a composite literal:
type location struct {
lat, long float64
}
curiosity := location{lat.decimal(), long.decimal()}
If you need a composite literal that’s anything more than a list of
values, consider writing a constructor function. The following listing
declares a constructor function named newLocation.
// newLocation from latitude, longitude d/m/s coordinates.
func newLocation(lat, long coordinate) location {
return location{lat.decimal(), long.decimal()}
}
Classical languages provideconstructors as a special language feature
to construct objects. Python has_init_, Ruby hasinitialize, and
PHP has__construct(). Go doesn’t have a language feature for
constructors. InsteadnewLocationis an ordinary function with a
name that follows a convention.
In this article we will learn about Go constructors and how to code constructors the easy way. This article will focus on creating constructors :
- Using Composite Literal
- Using Init method
- NewXxx constructor
Different methods to create golang constructor
Method-1: Using Composite Literal
This is the most simple and direct way of initializing a type in Go. This method has its disadvantages though.
Example
package main
import "fmt"
type Movie struct {
title string
rating int
}
func (m *Movie) printTitle() {
fmt.Printf("Movie title is :%s\n", m.title)
}
func (m *Movie) printRating() {
fmt.Printf("Rating is :%d \n", m.rating)
}
func main() {
m := Movie{
title: "Top Gun",
rating: 5,
}
m.printTitle()
m.printRating()
}
Explanation
In the above example we define a Movie struct with two fields. This
Movie type has two receiver functions namely printTitle() and
printRating(), that print the movie title and movie rating
respectively. In the main function we define a new movie m with
initial values for title and rating. We have constructed a new movie
struct using composite literals.
Output
$ go run main.go
Movie title is :Top Gun
Rating is :5
Method-2: Using Init method
We can initialize a type using a custom init() method.
Example
package main
import "fmt"
type Movie struct {
title string
rating int
}
func (m *Movie) init(title string, rating int) {
m.title = title
m.rating = rating
}
func (m *Movie) printTitle() {
fmt.Printf("Movie title is :%s\n", m.title)
}
func (m *Movie) printRating() {
fmt.Printf("Rating is :%d \n", m.rating)
}
func main() {
m := new(Movie)
m.init("Free Guy", 5)
m.printTitle()
m.printRating()
}
Explanation
In the above example, we define a Movie struct type with title and
rating fields. We also define a receiver init()
function that constructs a new movie type.The
init()
function takes the title and rating as arguments, which are used to
construct a new movie type. The Movie struct also has two more receiver
functions namely printTitle() and printRating().
In the main function, we initialize a new Movie using the new()
function. The new() function in Go constructs all data types in Go
except channels and maps, with their respective zero values. It returns
a pointer to the memory location of the new type. In the above example,
we construct a new Movie type with title and rating fields
assigned values.
Output
$ go run main.go
Movie title is :Free Guy
Rating is :5
Method-3: NewXxx constructor
The naming
convention for this function is to start with the New word then
adding the name of the things you want to construct. For example, if you
want to create a new Movie, the function name will be NewMovie().This
function is a factory function and it therefore creates a new type of a
thing. For efficient memory usage, they can be defined to return a
pointer.
Example
package main
import "fmt"
type Movie struct {
title string
rating int
}
func (m *Movie) printTitle() {
fmt.Printf("Movie title is :%s\n", m.title)
}
func (m *Movie) printRating() {
fmt.Printf("Rating is :%d \n", m.rating)
}
func NewMovie(title string, rating int) *Movie {
m := &Movie{
title: title,
rating: rating,
}
return m
}
func main() {
m := NewMovie("Top Gun Maverick", 5)
m.printTitle()
m.printRating()
}
Explanation
In the above example, We define a Movie struct with title and
rating fields. The Movie type has two receiver functions
namely printTitle() and printRating().We also define a factory
function called NewMovie() that takes in as argument the title and
rating of a movie . This function constructs a new movie and returns a
pointer to the caller. In the main function,we create a new movie with
title and rating. The returned value (m) also has access to the
methods printTitle() and printRating()
Output
$ go run main.go
Movie title is :Top Gun Maverick
Rating is :5
Returning a value and an error from a constructor
Go takes error handling seriously , and it has a dedicated
package(errors) for error handling. An error might occur while
constructing a new type. In this section, we will learn how to return a
type and an error.
package main
import (
"errors"
"fmt"
"log"
)
type Movie struct {
title string
rating int
}
func (m *Movie) printTitle() {
fmt.Printf("Movie title is :%s\n", m.title)
}
func (m *Movie) printRating() {
fmt.Printf("Rating is :%d \n", m.rating)
}
func NewMovie(title string, rating int) (*Movie, error) {
if rating > 5 {
return nil, errors.New("Rate above 5")
}
m := &Movie{
title: title,
rating: rating,
}
return m, nil
}
func main() {
m, err := NewMovie("Top Gun Maverick", 6)
if err != nil {
log.Println(err)
} else {
m.printTitle()
m.printRating()
}
}
Explanation
In the above example, we have added an error type as part of the return
types in the NewMovie() function. We check if the rating is above 5
and return movie and an error. If a rating above 5 is passed, then we
will return nil for the movie and an error errors.New(“Rate above 5”)
to the caller.
$ go run main.go
2022/10/02 12:04:11 Rate above5
Summary
In this article , we learn about Go constructors. Go does not come with
constructors natively but provides ways to construct new types.
Combining methods and structures provides much of what classical
languages provide without introducing a new language feature.
Constructor functions are ordinary functions. We learn how to construct
a new type with composite literals, Using Init() method and finally
using the NewXxx() function.


