Home > Mobile >  When to use a getter method with struct and when to use the public method
When to use a getter method with struct and when to use the public method

Time:12-26

I am confused in following two approaches about when to use a public method and when to use a getter method ,and which is better approach

I have this file in packagea

    package packagea
    
    type A struct {
        name  string
        email string
    }
    
    func (a *A) NewMock() *A {
        return &A{"logan", "rrrr"}
    }

func NewMock2() *A {
    return &A{"logan", "rrrr"}
}

And this file in package demo

package demo

func GetIt() {

    b := new(packagea.A)
    a := b.NewMock()         // Using getter
    c := packagea.NewMock2() //directly calling the method

    fmt.Println(a) //&{logan rrrr}
    fmt.Println(c) //&{logan rrrr}

}

They both print the same thing ,but I am confused when to use which .Please help me out.Thanks

CodePudding user response:

In general a constructor of an object should be a plain function, so your second example is fine.

It is good to have a function to construct your object if there is many fields or you have some small logic or validation.

For simple object like your example, allocating the object directly and made the fields public will be also good.

In your first example you allocate an object b, just for the sake of calling a method to allocate the object you really want.

An this is not good, as to pollute the memory with objects you never need.

b is built by assigning default values to the struct's fields, that are empty strings.

If the default values are just fine, you can think to adopt specific setter methods, instead of a constructor.

func (a *A) SetName(n: string) {
    a.name = n
}

func (a *A) SetEmail(e: string) {
    a.email = e
}

CodePudding user response:

Philosophically speaking

  1. If you want your constructor to handle allocating and creating a default struct value for you then:

     package packagea
     func NewMock2() *A {
         return &A{"logan", "rrrr"}
     }
    
  2. If you want your constructor to handle creation and initialization to provided arguments:

     package packagea
     func NewMock2(name, email string) *A {
         return &A{name, email}
     }
    
  3. If you want creation to be decoupled and your constructor does not need to bother how or where the value was created and only update attribute values:

     package packagea
     type A struct {
         name  string
         email string
     }
     func (a *A) NewA(name string, email string) {
         if a == nil {
             panic(fmt.Errorf("nil pointer"))
         }
         a.name = name
         a.email = email
     }
    

CodePudding user response:

First, you need to understand how new function works

In Go new is built-in functions that allocate memory but not it does not initialize the memory.

here b := new(packagea.A) it allocates the memory and returns the pointer to that memory so that you can access that memory by using that pointer. because b is a pointer you can initial value for name and email like this

b.name = "FOO"
b.email = "[email protected]"

but here you have a method which is a pointer receiver.

func (a *A) NewMock() *A {
    return &A{"logan", "rrrr"}  //composite literals.
}

so here you are repeating the same thing allocation of memory (which is already done by new function) and initializing the value in memory. Don't repeat yourself.

Now Let's talk about the second way.

c := packagea.NewMock2() //directly calling the method

func NewMock2() *A {
    return &A{"logan", "rrrr"}
}

here you doing a simple thing which is allocation of memory and initializing the value in memory.

but I am confused about when to use which. Please help me out.

When to use new function when there is no need for initialization. for Example

type A struct {
    buffer  bytes.Buffer
}

like here when you do this b := new(A) now the zero value for Buffer is an empty buffer ready to use. so use new when no need of initialization and ready to use. new always returns "Pointer" and default zero value again the type.

here NewMock2() is also a function but with your own logic inside it with full control. you can pass parameters or not. you can return value sematic or pointer sematic it is up to you. You can think like this before running the Car you need to initialize the car components because you cannot run the car if the car is not initialized.

  •  Tags:  
  • go
  • Related