Golang Constructor Tutorial

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:

Advertisement
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 provide constructors as a special language feature to construct objects. Python has _init_, Ruby has initialize, and PHP has __construct(). Go doesn’t have a language feature for constructors. Instead newLocation is 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 :

  1. Using Composite Literal
  2. Using Init method
  3. 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

Advertisement

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()

Advertisement

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 above 5

 

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.

Advertisement

 

Further Reading

Golang Constructor

 

 

Categories GO

Didn't find what you were looking for? Perform a quick search across GoLinuxCloud

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

Leave a Comment

X