guide Archives - Welcome To Golang By Example https://vikasboss.github.io/tag/guide/ Tue, 05 Jan 2021 17:37:40 +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 guide Archives - Welcome To Golang By Example https://vikasboss.github.io/tag/guide/ 32 32 159787465 Understand If Else Statement in Go (Golang) https://vikasboss.github.io/understand-if-else-statement-golang/ https://vikasboss.github.io/understand-if-else-statement-golang/#comments Sat, 02 May 2020 09:23:33 +0000 https://vikasboss.github.io/?p=2088 This is the  chapter 12 of the golang comprehensive tutorial series. Refer to this link for other chapters of the series – Golang Comprehensive Tutorial Series Next Tutorial – SwitchPrevious Tutorial – For Range loop Now...

The post Understand If Else Statement in Go (Golang) appeared first on Welcome To Golang By Example.

]]>
This is the  chapter 12 of the golang comprehensive tutorial series. Refer to this link for other chapters of the series – Golang Comprehensive Tutorial Series

Next Tutorial – Switch
Previous Tutorial – For Range loop

Now let’s check out the current tutorial. Below is the table of contents for current tutorial.

Overview

Go has if-else statement similar to any other programming language to perform the basic conditional logic. Below is the format for if-else statement in golang

if condition {
   //Do something
} else if condition {
   //Do something
} else {
   //Do something

Before we move further let’s talk about the condition first. Only a statement or a combination of statements that result in a boolean are allowed for a condition in if. false boolean is treated as false in a condition in go and true boolean is treated as true. As mentioned above, the condition can be composed of multiple statements combined by operators in Go such as &&, ||, >, <, >=, <=, ! etc.

Now let’s look into the if-else statement in detail to understand the small things. Go supports below formats for the if-else statement

  • Only if
  • If Else
  • If Else Ladder
  • Nested if-else
  • If with a short statement

If statement

if statement alone has below format

if condition {
   //Do something
}

If the condition is true then the statement inside the braces is executed.  Some points to note about if statement

  • Brackets can be omitted around the condition.
  • Opening and closing braces after condition are mandatory

Let’s see a working example. Below program checks if a number is greater than 5.

package main

import "fmt"

func main() {
    a := 6
    if a > 5 {
        fmt.Println("a is greater than 5")
    }
}

Output

a is greater than 5

Let’s see another example of multiple statement in a if condition. Below is a program to check if a number lies in a particular range. Notice that multiple statement in the condition are joined by the && operator.

package main

import "fmt"

func main() {
    a := 4
    if a > 3 && a < 6 {
        fmt.Println("a is within range")
    }
}

Output

a is within range

If Else Statement

If Else statement has below format

if condition {
   //Do something
} else {
   //Do something
}

If the condition is true then the statement inside the if block is executed otherwise the statement inside the else block is executed. Some points to note about if-else statement.

  • The else keyword should be on the same line as the closing brace for it. If not there will be below compiler error.
syntax error: unexpected else, expecting }

Let's see a small example of if else statement. In below program we use if else statement to figure out the max number of 2 numbers

package main

import "fmt"

func main() {
    a := 1
    b := 2

    if a > b {
        fmt.Println("a is greater than b")
    } else {
        fmt.Println("b is greater than a")
    }
}

Output

b is greater than a

If Else Ladder

If Else ladder has the below format

if condition1 {
   //Do something
} else if condition2 {
   //Do something
} else {
  //Do something
}

Some points to note about this if else ladder

  • Any number of else if statement can be added in the middle
  • else if should lie on the same line as the previous closing brace

Below is a working code example. The code given an age is using a if else ladder to find out weather a person is "Kid", "Young" or "Old".

package main

import "fmt"

func main() {
    age := 29
    if age < 18 {
        fmt.Println("Kid")
    } else if age >= 18 && age < 40 {
        fmt.Println("Young")
    } else {
        fmt.Println("Old")
    }
}

Output:

Young

Nested If Else

Below are some one of the possible format for nested if else.

Only nested if

if condition {
  //Do something
  if condition2 { 
    //Do something
  }
  //Do something
}

Nested if else

if condition1 {
   //....
   if condition2 {
      //...
   } else {
      //...
   }
  //...
}

Below combination is also possible for nested if else

if condition1 {
   //...
} else {
   //...
   if condition2 {
      //...
   } else {
     //....
   }
   //....
}

Let's see a working example of nested if else. In below program we print the max of three numbers using nested if else.

package main

import "fmt"

func main() {
    a := 1
    b := 2
    c := 3
    if a > b {
        if a > c {
            fmt.Println("Biggest is a")
        } else if b > c {
            fmt.Println("Biggest is b")
        }
    } else if b > c {
        fmt.Println("Biggest is b")
    } else {
        fmt.Println("Biggest is c")
    }
}

Output:

Biggest is c

If with short statement

If statement also supports a statement before the condition. This statement will be executed before the condition. There can also be new initialized variable in the statement. Below is the format for that.

if statement; condition {
   //Do something
}

The initialization if present in the statement will be a short declaration. Notice that var keyword is not supported in the statement. Let's see a working example

package main

import "fmt"

func main() {
    if a := 6; a > 5 {
        fmt.Println("a is greater than 5")
    }
}

Output

a is greater than 5

The variable that is initialized in if statement is available inside all the branches. As in below example variable a is also available in the else block.

package main

import "fmt"

func main() {
    if a := 1; a > 5 {
        fmt.Println("a is greater than 5")
    } else {
        fmt.Println("a is less than 5")
    }
}

Output:

a is less than 5

If Conditions

We mentioned at the start that only boolean values or statement that result in boolean value are allowed in the if condition. Let's see a working code of the error that comes in case of using any else than boolean

package main

import "fmt"

func main() {
    if 1 {
        fmt.Println("a is greater than 5")
    }
}

Output: Below compiler error is raised

non-bool 1 (type int) used as if condition

Ternary Operator

There is no ternary operator in Go, hence you need to use if else statements in place of that.

Conclusion

That is all about if else statement in go. Hope you have liked this article. Please share feedback/improvements/mistakes in comments

Next Tutorial – Switch
Previous Tutorial – For Range loop

The post Understand If Else Statement in Go (Golang) appeared first on Welcome To Golang By Example.

]]>
https://vikasboss.github.io/understand-if-else-statement-golang/feed/ 2 2088
Function in Go (Golang) https://vikasboss.github.io/function-golang-complete-guide/ https://vikasboss.github.io/function-golang-complete-guide/#comments Wed, 08 Apr 2020 11:41:31 +0000 https://vikasboss.github.io/?p=1952 This is the  chapter 8 of the golang comprehensive tutorial series. Refer to this link for other chapters of the series – Golang Comprehensive Tutorial Series Next Tutorial – ConstantsPrevious Tutorial –All basic data types Now...

The post Function in Go (Golang) appeared first on Welcome To Golang By Example.

]]>
This is the  chapter 8 of the golang comprehensive tutorial series. Refer to this link for other chapters of the series – Golang Comprehensive Tutorial Series

Next Tutorial – Constants
Previous Tutorial –All basic data types

Now let’s check out the current tutorial. Below is the table of contents for current tutorial.

Overview


A function is a group of statements that perform a specific task. In GO functions are first-order variables. They can be passed around like any other variable. 

Some point worth noting about a function name

  • A function name cannot begin with a number
  • The function name is case sensitive. Hence sum, Sum,  SUM are different functions. 
  • A function whose name starts with a capital letter will be exported outside its package and can be called from other packages. A function whose name starts with lowercase letters will not be exported and it’s only visible within its package.

Signature of a function

func func_name(input_parameters) return_values{
  //body
}

A function in golang

  • Declared using func keyword
  • It has a name
  • Comma-separated zero or more input parameters
  • Comma-separated zero or more return values
  • Function body
  • Can return multiple values

An example of a function. The below function is

  • Has the name “sum”
  • Accept two arguments of int type
  • Return a single value of type int
func sum(a int, b int) int {
  return a + b 
}

Calling a function

A function in Go can be called in go as below

results := sum(2, 3)

Some points to note about calling a function

  • If the function of some other package is being called then it is necessary to prefix the package name. Also please note that across packages only those function can be called which are exported meaning whose name start with capital letter
  • With in the same package the function can directly be called using its name suffixed by ()

Function Parameters

  • As mentioned above function can have zero or more arguments.
  • type for the consecutive same types can be specified only once. For example above sum function can also be written as
func sum(a, b int)
  • A copy of all the arguments is made while calling a function.

Return Values

  • As mentioned above a function can have one or more return values. Assume there is a function sum_avg that returns two values: Sum and Average. Example of multiple return values
func sum_avg(a, b int) (int, int)
  • As a convention error is returned as the last argument in a function. Example
func sum(a, b int) (int, error)
  • Collecting multiple return values in the caller function. In below example
result, err := sum(2, 3) 

Named Return Values

A go function can have named return values. With named return values , the return values did not need to be initialised in the function. The named variables are specified in the signature itself. Without named values,  only return type is specified. It is also ok to name some of the return values. For other return values only type can be specified. 

  • See example below: result is the named return value
func sum(a, b int) (result int)
  • With named return values, type of the consecutive same types can be specified only once
func sum_avg(a, b int) (sum, avg int)

Function Usages

  • Generic usage
  • Function as Type
  • Function as Values

The difference between function as type and function as values is that in type we only use the function signature whereas in function as value signature along with the body is used.  Let’s see each of this in detail so it is more clear

Generic Usage

Below is an example of the general usage of a function. We have a function sum in the below example which takes in two ints as input arguments and returns the sum.

package main

import "fmt"

func main() {
    res := sum(2, 3)
    fmt.Println(res)
}

func sum(a, b int) int {
    return a + b
}

Output:

5

Function as  Type

In go function is also a type. Two function will be of same type if

  • They have the same number of arguments with each argument is of the same type
  • They have same number of return values and each return value is of same type. 

Function type is useful in 

  • In the case of higher-order functions as we have seen in the above example. The argument and return type is specified using function type
  • In the case of defining interfaces in go as in the interface, only the function type is specified. Whatever implements this interface has to define a function of the same type

Let’s see an example of function type in the interface. Notice that the interface shape only defines the type of function

area() int
getType() string

Code:

package main
import "fmt"
func main() {
    var shapes []shape
    s := &square{side: 2}
    shapes = append(shapes, s)
    r := &rectangle{length: 2, breath: 3}
    shapes = append(shapes, r)
    for _, shape := range shapes {
        fmt.Printf("Type: %s, Area %d\n", shape.getType(), shape.area())
    }
}
type shape interface {
    area() int
    getType() string
}
type rectangle struct {
    length int
    breath int
}
func (r *rectangle) area() int {
    return r.length * r.breath
}
func (r *rectangle) getType() string {
    return "rectangle"
}
type square struct {
    side int
}
func (s *square) area() int {
    return s.side * s.side
}
func (s *square) getType() string {
    return "square"
}

Output:

Type: square, Area 4
Type: rectangle, Area 6

Function as User Defined Type

Function as user defined type can be declared using the type keyword

package main

import "fmt"

func main() {
    areaF := getAreaFunc()
    print(3, 4, areaF)
}

type area func(int, int) int

func print(x, y int, a area) {
    fmt.Printf("Area is: %d\n", a(x, y))
}

func getAreaFunc() area {
    return func(x, y int) int {
        return x * y
    }
}

Output:

12

Function as values (or Anonymous functions)

A function in Go is a first-order variable so it can be used as a value as well. It is also called as anonymous functions because a function is not named and can be assigned to a variable and passed around.

They are generally created for short term use or for limited functionality. See the below example. In this example variable max assigned a function. Since max is created by a function that is not named, it is an anonymous function.

package main

import "fmt"

var max = func(a, b int) int {
    if a >= b {
        return a
    }
    return b
}

func main() {
    res := max(2, 3)
    fmt.Println(res)
}

Output:

3

Special Usages of Function

Function Closures

Function closures are nothing but anonymous function which can access variables declared outside the function and also retain the current value between different function calls. Let’s see an example. In below case the count value is retained between different function calls of modulus function

package main

import (
    "fmt"
)

func main() {
    modulus := getModulus()
    modulus(-1)
    modulus(2)
    modulus(-5)
}

func getModulus() func(int) int {
    count := 0
    return func(x int) int {
        count = count + 1
        fmt.Printf("modulus function called %d times\n", count)
        if x < 0 {
            x = x * -1
        }
        return x
    }
}

Output:

modulus function called 1 times
modulus function called 2 times
modulus function called 3 times

Higher Order Function

Higher-order functions are those functions that either accept a function as a type or return function. Since the function is the first-order variable in Golang they can be passed around and also returned from some function and assigned to a variable. In below example

  • print function takes a function of type func(int, int) int as an argument
  • getAreafunc returns a function of type func(int, int) int
package main

import "fmt"

func main() {
    areaF := getAreaFunc()
    print(3, 4, areaF)
}

func print(x, y int, area func(int, int) int) {
    fmt.Printf("Area is: %d\n", area(x, y))
}

func getAreaFunc() func(int, int) int {
    return func(x, y int) int {
        return x * y
    }
}

Output:

12

IIF or Immediately Invoked Function

IIF or Immediately Invoked Function are those function which can be defined and executed at the same time.

package main

import "fmt"

func main() {
    squareOf2 := func() int {
        return 2 * 2
    }()
    fmt.Println(squareOf2)
}

Output:

4

Use Cases of IIF functions

  • When you don't want to expose the logic of the function either within or outside the package. For eg let's say there is a function which is setting some value. You can encapsulate all the logic of setting in an IIF function. This function won't be available for calling either outside or within the package.

Variadic Function

In Go, a function that can accept a dynamic number of arguments is called a Variadic function. Below is the syntax for variadic function. Three dots are used as a prefix before type.

func add(numbers ...int)

Code:

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

Methods

Method has a receiver argument. When you attach a function to a type, then that function becomes a method for that type. 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.

Function:

func some_func_name(arguments) return_values

Method:

func (receiver receiver_type) some_func_name(arguments) return_values

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.

Conclusion

This is all about function in golang. Hope you have liked this article. Please share feedback or mistakes/improvements in comments.

Next Tutorial – Constants
Previous Tutorial –All basic data types

The post Function in Go (Golang) appeared first on Welcome To Golang By Example.

]]>
https://vikasboss.github.io/function-golang-complete-guide/feed/ 1 1952
Abstract Class in GO: Complete Guide https://vikasboss.github.io/go-abstract-class/ https://vikasboss.github.io/go-abstract-class/#respond Sun, 18 Aug 2019 15:02:35 +0000 https://vikasboss.github.io/?p=203 Go Interface doesn’t have fields and also it doesn’t allow the definition of methods inside it. Any type needs to implements all methods of interface to become of that interface type. There...

The post Abstract Class in GO: Complete Guide appeared first on Welcome To Golang By Example.

]]>
Go Interface doesn’t have fields and also it doesn’t allow the definition of methods inside it. Any type needs to implements all methods of interface to become of that interface type. There are use cases where it is useful to have a default implementation of a method and also default fields in GO. Before understanding how to do it lets first understand the requirements of an abstract class:

  1. Abstract class should have default fields
  2. Abstract class should have the default method
  3. It should not be possible to create a direct instance of the abstract class

We will use a combination of a interface (abstract interface) and struct (abstract concrete type). Together they can provide the functionalities of an abstract class. See the below program:

package main

import "fmt"

//Abstract Interface
type iAlpha interface {
    work()
    common()
}

//Abstract Concrete Type
type alpha struct {
    name string
}

func (a *alpha) common() {
    fmt.Println("common called")
}

//Implementing Type
type beta struct {
    alpha
}

func (b *beta) work() {
    fmt.Println("work called")
    fmt.Printf("name is %s\n", b.name)
    b.common()
}

func main() {
    a := alpha{
        name: "test",
    }
    b := &beta{
        alpha: a,
    }
    b.work()
}

Output:

work called
name is test
common called

In above program:

  • We created an abstract interface iAlpha, an abstract concrete struct alpha, and an implementor struct beta
  • alpha struct is embedded in beta struct
  • The beta struct is able to access default field “name”
  • The beta struct is able to access the default method “common”
  • It is not able to create a direct instance of iAlpha  as alpha struct only implement only one of the method of iAlpha.

So it fulfills all three requirements but there is also one limitation of the above method. It is not possible to call the “work” method from “common” method of alpha. Basically there is no way to call an undefined method of the abstract interface from default methods of an abstract concrete type. There is one way to fix it, though. See below program

package main

import "fmt"

//Abstract Interface
type iAlpha interface {
    work()
    common()
}

//Abstract Concrete Type
type alpha struct {
    name string
    work func()
}

func (a *alpha) common() {
    fmt.Println("common called")
    a.work()
}

//Implementing Type
type beta struct {
    alpha
}

func (b *beta) work() {
    fmt.Println("work called")
    fmt.Printf("name is %s\n", b.name)
}

func main() {
    a := alpha{
        name: "test",
    }
    b := &beta{
        alpha: a,
    }
    b.alpha.work = b.work
    b.common()
}

Output:

common called
work called
name is test

In the above program:

  • We created a new field “work” of type func in alpha
  • We assigned alpha’s “work” method to beta “work” method

The only problem with the above program is that it is possible to create a direct instantiation of alpha struct and by providing the definition of work method, an instance of type iAlpha is created. This violates point 3 of the above Abstract class requirement as without creating our own new type we are able to create a type of iAlpha. Let’s try to fix this problem. The below program additionally also solves the problem where it was not possible to call the undefined methods from default methods.

package main

import "fmt"

//Abstract Interface
type iAlpha interface {
    work()
    common(iAlpha)
}

//Abstract Concrete Type
type alpha struct {
    name string
}

func (a *alpha) common(i iAlpha) {
    fmt.Println("common called")
    i.work()
}

//Implementing Type
type beta struct {
    alpha
}

func (b *beta) work() {
    fmt.Println("work called")
    fmt.Printf("Name is %s\n", b.name)
}

func main() {
    a := alpha{
        name: "test",
    }
    b := &beta{
        alpha: a,
    }
    b.common(b)
}

Output:

common called
work called
Name is test

In the above program:

  •  All the default methods will accept the first argument of interface type iAlpha. All the undefined methods of alpha struct will be called using this argument from default methods.

Conclusion: We can see in the above program that we are able to fulfill all three requirements of an abstract class. This is one of the ways to simulate abstract class in GO.

The post Abstract Class in GO: Complete Guide appeared first on Welcome To Golang By Example.

]]>
https://vikasboss.github.io/go-abstract-class/feed/ 0 203