method Archives - Welcome To Golang By Example https://vikasboss.github.io/tag/method/ Fri, 19 Jun 2020 20:48:51 +0000 en-US hourly 1 https://wordpress.org/?v=6.8.1 https://i0.wp.com/golangbyexamples.com/wp-content/uploads/2021/05/cropped-go_border-1.png?fit=32%2C32&ssl=1 method Archives - Welcome To Golang By Example https://vikasboss.github.io/tag/method/ 32 32 159787465 Method on a non-struct type in Go (Golang) https://vikasboss.github.io/method-non-struct-type-golang/ https://vikasboss.github.io/method-non-struct-type-golang/#respond Fri, 19 Jun 2020 20:48:38 +0000 https://vikasboss.github.io/?p=2283 Methods can also be defined on a non-struct custom type. Non-struct custom types can be created through type definition. Below is the format for creating a new custom type For example we...

The post Method on a non-struct type in Go (Golang) appeared first on Welcome To Golang By Example.

]]>
Methods can also be defined on a non-struct custom type. Non-struct custom types can be created through type definition. Below is the format for creating a new custom type

type {type_name} {built_in_type}

For example we can a named custom type myFloat of type float64

type myFloat float64

Methods can be defined on the named custom type. See below example:

Code

package main

import (
    "fmt"
    "math"
)

type myFloat float64

func (m myFloat) ceil() float64 {
    return math.Ceil(float64(m))
}

func main() {
    num := myFloat(1.4)
    fmt.Println(num.ceil())
}

Output

2

The post Method on a non-struct type in Go (Golang) appeared first on Welcome To Golang By Example.

]]>
https://vikasboss.github.io/method-non-struct-type-golang/feed/ 0 2283
Function/Method Overloading in Golang (Alternatives/Workaround) https://vikasboss.github.io/function-method-overloading-golang/ https://vikasboss.github.io/function-method-overloading-golang/#comments Sun, 01 Dec 2019 07:33:05 +0000 https://vikasboss.github.io/?p=783 Function/Method Overloading means that that the same function/method name can be used with a different number and types of parameters See this post for difference between function and method in Go –...

The post Function/Method Overloading in Golang (Alternatives/Workaround) appeared first on Welcome To Golang By Example.

]]>
Function/Method Overloading means that that the same function/method name can be used with a different number and types of parameters

See this post for difference between function and method in Go – https://vikasboss.github.io/difference-between-method-function-go

Eg.

func X()
func X(name string)
func X(name, address string)
func X(name string, age int)

Go doesn’t support method/function overloading. See this faq for the reason https://golang.org/doc/faq#overloading

According to the above faq things are simpler without it.

We can workaround Method/Function overloading in GO using

  • Variadic Function – A Variadic Function is a function that accepts a variable number of arguments
  • Empty Interface – It is an interface without any methods.

There are two cases for Method/Function Overloading

1.Different number of parameters but of the same type:

Above case can easily be handled using variadic functions. Notice in below code the parameters are of one type i.e. int.

package main

import "fmt"

func main() {
    fmt.Println(add(1, 2))
    fmt.Println(add(1, 2, 3))
    fmt.Println(add(1, 2, 3, 4))
}

func add(numbers ...int) int {
    sum := 0
    for _, num := range numbers {
        sum += num
    }
    return sum

Output:

3
6
10

2.Different number of parameters and of different types

This case can be handled using both variadic function and empty interface

package main

import "fmt"

func main() {
    handle(1, "abc")
    handle("abc", "xyz", 3)
    handle(1, 2, 3, 4)
}

func handle(params ...interface{}) {
    fmt.Println("Handle func called with parameters:")
    for _, param := range params {
        fmt.Printf("%v\n", param)
    }
}

Output:

Handle func called with parameters:
1
abc
Handle func called with parameters:
abc
xyz
3
Handle func called with parameters:
1
2
3
4

We can also use a switch case to get the exact parameters and use them accordingly. See the below example.

package main

import "fmt"

type person struct {
    name   string
    gender string
    age    int
}

func main() {
    err := addPerson("Tina", "Female", 20)
    if err != nil {
        fmt.Println("PersonAdd Error: " + err.Error())
    }
    
    err = addPerson("John", "Male")
    if err != nil {
        fmt.Println("PersonAdd Error: " + err.Error())
    }
     
    err = addPerson("Wick", 2, 3)
    if err != nil {
        fmt.Println("PersonAdd Error: " + err.Error())
    }
}

func addPerson(args ...interface{}) error {
    if len(args) > 3 {
        return fmt.Errorf("Wront number of arguments passed")
    }
    p := &person{}
    //0 is name
    //1 is gender
    //2 is age
    for i, arg := range args {
        switch i {
        case 0: // name
            name, ok := arg.(string)
            if !ok {
                return fmt.Errorf("Name is not passed as string")
            }
            p.name = name
        case 1:
            gender, ok := arg.(string)
            if !ok {
                return fmt.Errorf("Gender is not passed as string")
            }
            p.gender = gender
        case 2:
            age, ok := arg.(int)
            if !ok {
                return fmt.Errorf("Age is not passed as int")
            }
            p.age = age
        default:
            return fmt.Errorf("Wrong parametes passed")
        }
    }
    fmt.Printf("Person struct is %+v\n", p)
    return nil
}

Note: Wherever the arg is not passed it is substituted as default.

Output:

Person struct is &{name:Tina gender:Female age:20}
Person struct is &{name:John gender:Male age:0}
PersonAdd Error: Gender is not passed as string

The post Function/Method Overloading in Golang (Alternatives/Workaround) appeared first on Welcome To Golang By Example.

]]>
https://vikasboss.github.io/function-method-overloading-golang/feed/ 1 783
Difference between method and function in GO https://vikasboss.github.io/difference-between-method-function-go/ https://vikasboss.github.io/difference-between-method-function-go/#respond Sun, 01 Dec 2019 07:02:54 +0000 https://vikasboss.github.io/?p=777 There are some important differences between method and function. Let’s see the signature of both Function: Method: From the above signature, it is clear that method has a receiver argument. A receiver...

The post Difference between method and function in GO appeared first on Welcome To Golang By Example.

]]>
There are some important differences between method and function. Let’s see the signature of both

Function:

func some_func_name(arguments) return_values

Method:

func (receiver receiver_type) some_func_name(arguments) return_values


From the above signature, it is clear that method has a receiver argument. A receiver can be a struct or any other type. The method will have access to the properties of the receiver and can call the receiver’s other methods.
This is the only difference between function and method, but due to it they differ in terms of functionality they offer

  • A function can be used as first-order objects and can be passed around while methods cannot.
  • Methods can be used for chaining on the receiver while function cannot be used for the same.
  • There can exist different methods with the same name with a different receiver, but there cannot exist two different functions with the same name in the same package.

The post Difference between method and function in GO appeared first on Welcome To Golang By Example.

]]>
https://vikasboss.github.io/difference-between-method-function-go/feed/ 0 777
Template Method Design Pattern in Go (Golang) https://vikasboss.github.io/template-method-design-pattern-golang/ https://vikasboss.github.io/template-method-design-pattern-golang/#comments Sat, 30 Nov 2019 13:28:50 +0000 https://vikasboss.github.io/?p=724 Note: Interested in understanding how all other design patterns can be implemented in GO. Please see this full reference – All Design Patterns in Go (Golang) Introduction: Template Method Design Pattern is...

The post Template Method Design Pattern in Go (Golang) appeared first on Welcome To Golang By Example.

]]>
Note: Interested in understanding how all other design patterns can be implemented in GO. Please see this full reference – All Design Patterns in Go (Golang)

Introduction:

Template Method Design Pattern is a behavioral design pattern that lets you define a template or algorithm for a particular operation.  Let’s understand the template design pattern with an example.

Consider the example of One Time Password or OTP. There are different types of OTP that can be triggered for eg. OTP can be SMS OTP or EMAIL OTP.  But irrespective it is an SMS OTP or EMAIL OTP,  the entire steps of the OTP process are the same.  The steps are

  • Generate a random n digit number. 
  • Save this number in the cache for later verification. 
  • Prepare the content
  • Send the notification
  • Publish the metrics

Even in the future let’s say a push notification OTP is introduced but still it will go through the above steps.

In such scenarios when the steps of a particular operation are the same but the steps of the operations can be implemented in a different way by different implementors , then that becomes a candidate for the Template Method Design Pattern. We define a template or algorithm which comprises of a fixed number of methods. The implementer of the operation overrides the methods of the template.

Now check out the below code example.

  • iOtp represents an interface that defines the set of methods that any otp type should implement
  • sms and email are the implementors of iOtp interface
  • otp is the struct which defines the template method genAndSendOTP(). otp embeds iOtp interface. 

Important: The combination of iOtp interface and otp struct provides the capabilities of Abstract Class in go. For reference see

Example

otp.go

package main

type iOtp interface {
    genRandomOTP(int) string
    saveOTPCache(string)
    getMessage(string) string
    sendNotification(string) error
    publishMetric()
}

type otp struct {
    iOtp iOtp
}

func (o *otp) genAndSendOTP(otpLength int) error {
    otp := o.iOtp.genRandomOTP(otpLength)
    o.iOtp.saveOTPCache(otp)
    message := o.iOtp.getMessage(otp)
    err := o.iOtp.sendNotification(message)
    if err != nil {
        return err
    }
    o.iOtp.publishMetric()
    return nil
}

sms.go

package main

import "fmt"

type sms struct {
    otp
}

func (s *sms) genRandomOTP(len int) string {
    randomOTP := "1234"
    fmt.Printf("SMS: generating random otp %s\n", randomOTP)
    return randomOTP
}

func (s *sms) saveOTPCache(otp string) {
    fmt.Printf("SMS: saving otp: %s to cache\n", otp)
}

func (s *sms) getMessage(otp string) string {
    return "SMS OTP for login is " + otp
}

func (s *sms) sendNotification(message string) error {
    fmt.Printf("SMS: sending sms: %s\n", message)
    return nil
}

func (s *sms) publishMetric() {
    fmt.Printf("SMS: publishing metrics\n")
}

email.go

package main

import "fmt"

type email struct {
    otp
}

func (s *email) genRandomOTP(len int) string {
    randomOTP := "1234"
    fmt.Printf("EMAIL: generating random otp %s\n", randomOTP)
    return randomOTP
}

func (s *email) saveOTPCache(otp string) {
    fmt.Printf("EMAIL: saving otp: %s to cache\n", otp)
}

func (s *email) getMessage(otp string) string {
    return "EMAIL OTP for login is " + otp
}

func (s *email) sendNotification(message string) error {
    fmt.Printf("EMAIL: sending email: %s\n", message)
    return nil
}

func (s *email) publishMetric() {
    fmt.Printf("EMAIL: publishing metrics\n")
}

main.go

package main

import "fmt"

func main() {
    smsOTP := &sms{}
    o := otp{
        iOtp: smsOTP,
    }
    o.genAndSendOTP(4)
    fmt.Println("")
    emailOTP := &email{}
    o = otp{
        iOtp: emailOTP,
    }
    o.genAndSendOTP(4)
}

Output:

SMS: generating random otp 1234
SMS: saving otp: 1234 to cache
SMS: sending sms: SMS OTP for login is 1234
SMS: publishing metrics

EMAIL: generating random otp 1234
EMAIL: saving otp: 1234 to cache
EMAIL: sending email: EMAIL OTP for login is 1234
EMAIL: publishing metrics

Full Working Code:

package main

import "fmt"

type iOtp interface {
    genRandomOTP(int) string
    saveOTPCache(string)
    getMessage(string) string
    sendNotification(string) error
    publishMetric()
}

type otp struct {
    iOtp iOtp
}

func (o *otp) genAndSendOTP(otpLength int) error {
    otp := o.iOtp.genRandomOTP(otpLength)
    o.iOtp.saveOTPCache(otp)
    message := o.iOtp.getMessage(otp)
    err := o.iOtp.sendNotification(message)
    if err != nil {
        return err
    }
    o.iOtp.publishMetric()
    return nil
}

type sms struct {
    otp
}

func (s *sms) genRandomOTP(len int) string {
    randomOTP := "1234"
    fmt.Printf("SMS: generating random otp %s\n", randomOTP)
    return randomOTP
}

func (s *sms) saveOTPCache(otp string) {
    fmt.Printf("SMS: saving otp: %s to cache\n", otp)
}

func (s *sms) getMessage(otp string) string {
    return "SMS OTP for login is " + otp
}

func (s *sms) sendNotification(message string) error {
    fmt.Printf("SMS: sending sms: %s\n", message)
    return nil
}

func (s *sms) publishMetric() {
    fmt.Printf("SMS: publishing metrics\n")
}

type email struct {
    otp
}

func (s *email) genRandomOTP(len int) string {
    randomOTP := "1234"
    fmt.Printf("EMAIL: generating random otp %s\n", randomOTP)
    return randomOTP
}

func (s *email) saveOTPCache(otp string) {
    fmt.Printf("EMAIL: saving otp: %s to cache\n", otp)
}

func (s *email) getMessage(otp string) string {
    return "EMAIL OTP for login is " + otp
}

func (s *email) sendNotification(message string) error {
    fmt.Printf("EMAIL: sending email: %s\n", message)
    return nil
}

func (s *email) publishMetric() {
    fmt.Printf("EMAIL: publishing metrics\n")
}

func main() {
    smsOTP := &sms{}
    o := otp{
        iOtp: smsOTP,
    }
    o.genAndSendOTP(4)
    fmt.Println("")
    emailOTP := &email{}
    o = otp{
        iOtp: emailOTP,
    }
    o.genAndSendOTP(4)
}

Output:

SMS: generating random otp 1234
SMS: saving otp: 1234 to cache
SMS: sending sms: SMS OTP for login is 1234
SMS: publishing metrics

EMAIL: generating random otp 1234
EMAIL: saving otp: 1234 to cache
EMAIL: sending email: EMAIL OTP for login is 1234
EMAIL: publishing metrics

The post Template Method Design Pattern in Go (Golang) appeared first on Welcome To Golang By Example.

]]>
https://vikasboss.github.io/template-method-design-pattern-golang/feed/ 2 724