Browse by Domains

GoLang Tutorial | Go Programming Language for Beginners

Introduction

In 2007, three great engineers – Robert Griesemer, Rob Pike and Ken Thompson came together and created GO language. They took the advantageous features from C, Python and Java, combined all of them in to GO to develop scalable systems. Below are the salient features of GO. Taking up a Golang course will also help you learn more.

  • Strong and Simple Type System
  • Lightning Fast Compiler
  • Built-in Concurrency Support
  • Supports Garbage Collection

Environment Setup

Download your operating system specific binary from https://golang.org/dl/

Follow the corresponding installation instruction from https://golang.org/doc/install

Typical program structure

A typical GO programs consists of the below high-level elements:

package <package_name>
import “<package_name>”
func main() {
  //executable code
}

Go programs are organized as packages. Hence, the package name should be defined.

Import statements facilitate to use of external code.

The Main is the entry point. The program execution starts from here.

Variables

Variable is used to store data in memory in Go. Go being a statically typed language, every variable must be assigned a type (more details on type in next section). The type cannot be changed once assigned. The type can be in one of the following ways:

  • Explicitly – by mentioning the type in the variable declaration.
  • Implicitly – Leveraging compiler’s feature to infer the type based on the value assigned to the variable.

Below are the rules to be followed to construct valid variable names.

  • It can consist of alphanumeric and underscore.
  • It must start with an alphabet or an underscore.
  • It is case-sensitive i.e., uppercase and lowercase letters are treated differently.

Variable Definition, Declaration and Initialization

In GO, the variable definition means to mention the name of one or more variables and the type of those variables. The type can be either GO built-in types or user-defined type. Below is the general syntax of variable declaration.

  var comma_separated_list_of_variable_names data_type;

  Note: data_type is not mandatory as GO compiler infers it based on the value assigned to the variable.

  Below are some examples of valid definitions

  var l, m, n int;

  var binary byte;

  var temperature float32;

  Shown below is the syntax to assign an initial value to the variable

  name_of_variable = initial_value;

 ex: l = 5;

  Explicit Type Declaration

   In this type of declaration, the variable type is explicitly specified as part of the variable definition.

   ex: var temperature float32

       temperature = 45.0

  Implicit Type Declaration

 In this type of declaration, the variable type is not specified in the variable definition. The compiler infers the type based on the value assigned.

    Below is the syntax:

       variable_name := initial_value

      ex: salary := 100

Data Types

This section covers the built-in data types supported in Go. The data type is a classification that specifies the kind of value a variable holds. Based, on the data type of variable, the compiler decides how much memory space to allocate and how to interpret the binary content of the value stored in the variable.

Go provides the following categories of primitive data types.

  • Boolean
  • Numeric
    • Integer
    • Float Point
    • Others
  • String

Below table lists the purpose of each data type and the range of value that can be stored in them.

TypeDescriptionRange
BooleanUsed to store Boolean values – true or falseNot Applicable.
Integer: uint8Unsigned 8-bit integers0 to 255
Integer: uint16Unsigned 32-bit integers0 to 65535
Integer: uint32Unsigned 32-bit integers0 to 4294967295
Integer: unit64Unsigned 64-bit integers0 to 18446744073709551615
Integer: int8Signed 8-bit integers-128 to 127 
Integer: int16Signed 16-bit integers-32768 to 32767
Integer: int32Signed 32-bit integers-2147483648 to 2147483647
Integer: int64Singed 64-bit integers-9223372036854775808 to 9223372036854775807
Float: float32IEEE-754 32-bit floating-point numbers
Float: float64IEEE-754 64-bit floating-point numbers
Float: complex64Complex numbers with float32 real and imaginary parts
Float: complex128Complex numbers with float64 real and imaginary parts
Others: byteAlias for uint8
Others: runeAlias for int32
Others: uintEither 32 or 64 bits
Others: uintptran unsigned integer large enough to store the uninterpreted bits of a pointer value
Others: intSame size as uint

Operators 

An operator is a programming construct to instruct the computer to process the variables/operands to achieve the desired goal like adding two numbers, evaluating an expression and comparing it to true or false etc.

GO provides the below built-in rich set of operators.

  • Arithmetic Operators
  • Relational Operators
  • Logical Operators
  • Bitwise Operators
  • Assignment Operators
  • Miscellaneous Operators 

Arithmetic Operators: Below table lists the arithmetic operators supported in GO.

OperatorDescription
+This operator performs the sum of two operands by adding them.
This operator finds the difference between the two operands. It subtracts the second from the first operand.
*This operator finds the product of two operands by multiplying them.
/This operator performs the integer division of two operands. It yields a quotient that will be of type integer.
%This is known as the Modulus operator. It is used to find the integer remainder of two operands.
++This is a unary increment operator. It is used to increase the integer value by one.
This is a unary decrement operator. It is used to reduce the integer value by one.

Relational Operators: Below table lists the relational operators supported in GO.

OperatorDescription
==This is the equality operator that will be used to find if two values are equal.
!=This is the inequality operator that will be used to confirm that two values are not equal.
>This is the greater than operator that will be used to check if one operand is higher than the other operand.
<This is the less-than operator that will be used to check if one operand is lower than the other operand.
>=This is the greater than or equal to operator that will be used to check if one operand is higher than or equal to the other operand.
<=This is the less than or equal to the operator that will be used to check if one operand is lower than or equal to the other operand.

Logical Operators: Below table lists the logical operators supported in GO.

OperatorDescription
&&This is the Logical AND operator that applies to boolean operands. It evaluates to true only when both the operands are true. When the left operand is false, the right operand is not evaluated. This is known as short-circuiting.
||This is the Logical OR operator that applies to boolean operands. It evaluates to true when either one of the operands(s) is/are true,  false otherwise.
!This is the Logical NOT Operator. It is used to negate the value stored in the operand i.e., if the value stored in operand is true, applying this operator, results in false and vice-versa.

Bitwise Operators: Below table lists the bitwise operators supported in GO.

OperatorDescription
&This is Binary AND Operator. It is applied to the binary representation of an integer. It evaluates from right to left. It evaluates to one if a bit in the respective position of both the operands is one else evaluates to zero. 
|This is a Binary OR Operator. It is applied to the binary representation of an integer. It evaluates from right to left. It evaluates to zero if a bit in the respective positions of both the operands is zero else evaluates to one.
^This is Binary XOR Operator. It is applied to the binary representation of an integer. It evaluates from right to left. It is evaluated to one if a bit in the respective positions of both the operands is different else evaluates to zero.
<<This is the Binary Left Shift Operator. The left operands value is shifted to the left by the number of bits specified in the right operand. This is effectively multiplying the number in the left operand by power(2, n), where n is the value in the right operand.
>>This is the Binary Right Shift Operator. The left operands value is shifted to the right by the number of bits specified by the right operand. This is effectively dividing the number in the left operand by power(2,n) where n is the value in the right operand.

Assignment Operators: Below table lists the assignment operators supported in GO.

OperatorDescription
=This is the assignment operator. It is used to assign value to a variable.
+=This is shortcut for adding value to current content of the variable and assigns the resultant value to the variable. 
-=This is a shortcut for subtracting value from the current content of the variable and assigns the resultant value to the variable.
*=This is a shortcut for multiplying value with the current content of the variable and assigns the resultant value to the variable.
/=This is the shortcut for dividing value from the current content of the variable and assigns the resultant value to the variable.
%=This is the shortcut for taking modulus value from the current content of the variable and assigns the resultant value to the variable.
<<=This is the shortcut for the left shifting the current content of the variable and assigns the resultant value to the variable.
>>=This is a shortcut for right shifting the current content of the variable and assigns the resultant value to the variable.
&=This is shortcut for doing bitwise AND of current content in the variable with the value in the right operand and assigns the resultant value to the variable.
^=This is a shortcut for doing bitwise XOR of current content in the variable with the value in the right operand and assigns the resultant value to the variable.
|=This is shortcut for doing bitwise OR of current content in the variable with the value in the right operand and assigns the resultant value to the variable.

Operator Precedence and Associativity: This determines how the operators are associated with each other in an expression and evaluated in the order of their priority. In the below table, operators are listed in the descending order of their priority.

CategoryOperator(s)Associativity
Postfix() [] -> . ++ – –Left to right
Unary+ – ! ~ ++ – – (type)* & sizeofRight to left
Multiplicative* / %Left to right
Additive+ –Left to right
Shift<< >>Left to right
Relational< <= > >=Left to right
Equality== !=Left to right
Bitwise AND&Left to right
Bitwise XOR^Left to right
Bitwise OR|Left to right
Logical AND&&Left to right
Logical OR||Left to right
Assignment= += -= *= /= %=>>= <<= &= ^= |=Right to left
Comma,Left to right

Decision Control Instructions

Decision control instructions also known as branching constructs are an important component of any program. It facilitates the addition of intelligence to the program. It allows the program to perform a different set of actions based on the state – result of evaluating an expression. Branching constructs consist of multiple conditions and a statement or block of statements associated with each condition. At any time, one of the conditions evaluates to true and statement(s) associated with that condition will be executed.

Below sections briefs each of the branching construct supported in Go programming.

If

An if statement has a Boolean expression associated with a statement or a set of statements.

Syntax:

if(booleanexpression){

/* statement(s) to execute */

How it works: First the Boolean expression is evaluated. Only if it evaluates to true, the statement(s) within the curly braces will be executed.

Example:

package main
 
import "fmt"
 
func main() {
   
   var score int = 10
 
   /* evaluate the condition */
   if( score < 35 ) {
      /* execute below code if condition is true */
      fmt.Printf("Grade: Fail\n" )
   }
   fmt.Printf("score: %d\n", score)
}

Compiling and executing the above code, gives the below result

Grade: Fail

Score: 10

If…else

Else block can follow an if statement. The code in the else block executes when the condition in the if statement evaluates to false.

Syntax: 

Syntax:

if(booleanexpression){

/* statement(s) to execute */

} else {

/* statement(s) to execute *

}

Example:

package main
 
import "fmt"
 
func main() {
   
   var score int = 40
 
   /* evaluate the condition */
   if( score < 35 ) {
      /* execute below code if condition is true */
      fmt.Printf("Grade: Fail\n" )
   } else {
       /* execute below code if condition is true */
      fmt.Printf("Grade: Pass\n" )
   }
   fmt.Printf("score: %d\n", score)
}

Compiling and executing the above code, gives the below result

Grade: Pass

Score: 40

if…else if…else

This construct is used to determine a single condition that will be true when several possibilities exist. In this construct, an if statement is followed by one or more else if statements and zero or one else statement.

Syntax:

               if(booleanexpression_1){

/* statement(s) to execute when booleanexpression_1 is true */

} else if(booleanexpression_2) {

/* statement(s) to execute when booleanexpression_2 is true */

} else if(booleanexpression_3) {

/* statement(s) to execute when booleanexpression_3 is true */

} else {

/* statement(s) to execute when all above conditions are false */

}

Example:

package main
 
import "fmt"
 
func main() {
   
   var score int = 30
 
   /* evaluate the condition */
   if( score >= 70 ) {
      /* execute below code if condition is true */
      fmt.Printf("Grade: Distinction\n" )
   } else if ( score >= 60 ) {
       /* execute below code if condition is true */
      fmt.Printf("Grade: First Class\n" )
   } else {
       /* execute below code if condition is true */
      fmt.Printf("Grade: Fail\n" )
   }
   fmt.Printf("score: %d\n", score)
}

Compiling and executing the above code, gives the below result

Grade: Fail

Score: 30

Nested if

This constructs allows to add if,  if-else block within the if block or the within the else block or both.

Syntax:

if(booleanexpression){
                      if(Booleanexpression1){
		/* statement(s) to execute */
	      } else {
                        	/* statement(s) to execute */
     }
              } else {
		if(Booleanexpression2){
		/* statement(s) to execute */
	      } else {
                        	/* statement(s) to execute */
     }
            }

Example:

package main
 
import "fmt"
 
func main() {
   
   var score int = 65
 
   /* evaluate the condition */
   if( score >= 30 ) {
      if ( score >= 70 ) {    
         /* execute below code if condition is true */
        fmt.Printf("Grade: Distinction\n" )
      } else if ( score >= 60 ) {
        /* execute below code if condition is true */
        fmt.Printf("Grade: First Class\n" )
      } else {
        /* execute below code if condition is true */
        fmt.Printf("Grade: Second Class\n" )      
      }  
   } else {
       /* execute below code if condition is true */
      fmt.Printf("Grade: Fail\n" )
   }
   fmt.Printf("score: %d\n", score)
}

Compiling and executing the above code, gives the below result

Grade: First Class

Score: 65

Switch

This control statement is a neater form of if…else if…. Else conditional instruction. This allows making a decision from a number of choices by comparing the content of a variable against a set of values possible for that variable.

Go supports the following types of switch statements:

Expression Switch – In this, case expression is compared against switch expression value.

Type Switch – In this, case type is compared against type of a specially annotated switch expression.

Expression switch:

Syntax:

switch (Boolean-expression | integer-expression){
                                    case Boolean-expr1 | integer-value1:
			statement(s);
                                     case Boolean-expr2 | integer-value2:
			statement(s);
                                    case Boolean-expr3 | integer-value3:
			statement(s);
                                      ……..
                                       ……..
                                     /* there can be multiple case statements */        
                                    default : /* Optional */
			statement(s);
                             }

Example:

package main
 
import "fmt"
 
func main() {
   
   var score int = 90
   var result string = “D”
 
   switch score {
        case 100: result = “A+”
        case 90: result = “A”
	  case 80: result = “B”
	  case 70,60: result = “C”
	  default: result = “D”  
   }
   
   fmt.Printf("Result : %s\n", result)
}

Compiling and executing the above code, gives the below result

Result: A

Type Switch:

   Syntax:

 switch x.(type){
                                    case type1:
			statement(s);
                                     case type2:
			statement(s);
                                     ……..
                                       ……..
                                     /* there can be multiple case statements */        
                                    default : /* Optional */
			statement(s);
                             }

Example:

package main
 
import "fmt"
 
func main() {
   var x interface{}
     
   switch i := x.(type) {
      case nil:	  
         fmt.Printf("type of x :%T",i)                
      case int:	  
         fmt.Printf("x is int")                       
      case float64:
         fmt.Printf("x is float64")           
      case func(int) float64:
         fmt.Printf("x is func(int)")                      
      case bool, string:
         fmt.Printf("x is bool or string")       
      default:
         fmt.Printf("don't know the type")     
   }   
}

Compiling and executing the above code gives the below result:

type of x :<nil>

Functions

 A function is a self-contained code block that performs a coherent task. It acts as a black-box by accepting inputs optionally and providing an output that is again optional.

Every Go program contains main() function by default.

Declaring a function means writing the function signature consisting of the function name, return type and parameters. Function definition comprises implementing the code in the function body that does the actual work.

Function components and it’s meaning is as below:

func functionname( [parameters] ) [return value with it’s type] 🡺  function-header

{

                    Function body

}

func: This is the keyword beginning the function declaration.

Function name: Name given to identify the function

Parameters: They are the inputs passed to the function. Each parameter is associated with a type.

The function can take zero or more parameters.

Return value and type:   Function may return a value or a list of values. The return type is associated with a type. The return value is optional. Some functions generate result as a effect of processing while some just change the state without generating any result.

Function Body: This is the work-horse of the function. It is the set of statements that does the actual processing and defines the work done.

Below is an example of a function called sum(). It takes two inputs number1 and number2 and return the value obtained by adding them.

func sum(number1, number2 int)  int {
	result int
	result = number1 + number2
	return result
}

Function call: The function calls another function. First is also known as the calling function while the latter is also known as called function. The calling function passes the required values in relevant order to the called function. Upon completion of the called function processing, it returns control to the called function.

Shown below is an example

package main
 
import "fmt"
 
func main() {
   var number1 int = 5
   var number2 int = 30
   var result int
 
   result = sum(number1, number2)
 
   fmt.Printf( "Sum is : %d\n", result)
}
 
func sum(n1, n2 int) int {
   var result int
 
   result = n1 + n2 	
   
   return result 
}

Compiling and executing the above code gives below output

Sum is: 35

Formal Parameters and Arguments: The parameters in the function header are known as formal parameters. The actual values passed from the calling function are known as arguments. The formal parameters are local to the function.

Following are the two different ways of calling function

Call by value: In this approach, the actual values/arguments are copied into the formal parameters of the function. So any changes to formal parameters within the function will have no effect on the arguments passed to the function. This is the default mode in GO.

Call by reference: In this approach, the address of arguments are copied to the format parameter. So, any changes to formal parameters are reflected in the arguments as they are accessed by address within the function.

Arrays

An array is the data structure that is a fixed-size continuous collection of homogenous elements i.e., all elements are of identical data type. 

Arrays are used to store collection of homogenous elements by declaring one array variable like student and use student[0], student[1], ……. ,student[n-1] instead declaring several individual variables like student1, student2, ….. , student

Arrays are subscript based data structure. The elements are accessed using subscript or index. Array index value starts from 0.

The below diagram is a pictorial representation of an array.

Array Declaration : Declaring an array means to mention the element type and the number of elements the array should store. Below is the syntax for declaring a one-dimensional array:

var var_name [array_size] var_type

array_size 🡺 must be an integer value greater than zero

var_type 🡺 any valid GO data type

Below code declares a one-dimensional array with 5 elements called scores of type int

var scores [5] int

Array Initialization :

Following are the direct ways to initialize array

Initialize a single array element : 

Syntax: array_name[index] = value

      The above syntax implies the specified value is assigned to the array element at mentioned index. Arrays being zero-based, 0 is the first element index/base index and the last element index is array_size – 1.

Ex: score[3] = 69

Initialize all the array elements:

     Method 1:

           Syntax: var array_name = [array_size] type {value0, value1, …… , valuearray_size-1}

      The number of values must not exceed the array_size

           Ex: var scores = [4]int{57,39,89,95}

       Method 2:

            Syntax: var array_name = [] type {value0, value1, …… , valuen}

           Ex: var scores = []int{57,39,89,95}

          In this case, array_size is sufficient enough to hold all the values with {}

Accessing Array Elements

  Arrays being subscript based data structures, it’s elements are accessed by using index of the element along with the array name.

     Syntax: array_name[index]

      Ex: int score = scores[2]

      In the above example, an element at index 2 from scores array is assigned to the score variable.

Below is the example which demo’s array declaration, assignment and accessing array elements.

package main
 
import "fmt"
 
func main() {
   var scores [5]int /* scores is an array of 5 integers */
   var len, len1 int
 
   /* initialize elements of array scores*/         
   for len = 0; len < 5; len++ {
      scores[len] = len + 100 
   }
   
   /* output each array element's value */
   for len1 = 0; len1 < 5; len++ {
      fmt.Printf("Score[%d] = %d\n", len1, scores[len1] )
   }
}

Compiling and executing above code gives below output

Scores[0] = 100

Scores[1] = 101

Scores[2] = 102

Scores[3] = 103

Scores[4] = 104

Avatar photo
Great Learning Team
Great Learning's Blog covers the latest developments and innovations in technology that can be leveraged to build rewarding careers. You'll find career guides, tech tutorials and industry news to keep yourself updated with the fast-changing world of tech and business.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top