02. Operators and Control Flow

Arindam BaidyaArindam Baidya
10 min read

Comparison Operators

  • Compare two operands and yield a Boolean value that is true or false.

  • Allow values of the same data type for comparisons

  • Common comparisons -

    • Does one string match another?

    • Are two numbers the same?

    • Is one number greater than another?

Equal to (==)

  • Returns True when the values are equal.
func main() {
    var city string = "Kolkata"
    var city_2 string = "Calcutta"

    fmt.Println(city == city_2)
}

// Output >> false

Not equal to (!=)

  • Returns True when the values are not equal.
func main() {
    var city string = "Kolkata"
    var city_2 string = "Calcutta"

    fmt.Println(city != city_2)
}

// Output >> True

Less than (<)

  • Returns True when the left operand is lesser than the right operand.
func main() {
    var a, b int = 5, 10

    fmt.Println(a < b)
}

// Output >> true

Less than or equal to (<=)

  • Returns True when the left operand is lesser or equal to the right operand.
func main() {
    var a, b int = 10, 10

    fmt.Println(a <= b)
}

// Output >> true

Greater than (>)

  • Returns True when the left operand is greater than the right operand.
func main() {
    var a, b int = 20, 10

    fmt.Println(a > b)
}

// Output >> true

Greater than or equal to (>=)

  • Returns True when the left operand is greater or equal to the right operand.
func main() {
    var a, b int = 20, 20

    fmt.Println(a >= b)
}

// Output >> true

Arithmetic Operators

  • Used to perform common arithmetic operations, such as addition, subtraction, multiplication, etc.

  • Common comparisons -

    • Does the sum of two numbers equal a particular value?

    • Is the difference between two numbers lesser than a particular value?

Addition (+)

  • Adds the left and right operands.
func main() {
    var a, b string = "foo", "bar"
    fmt.Println(a + b)
}

// Output >> foobar
  • Works on string as concatenation.

Subtraction (-)

  • Subtracts the right operand from the left operand
func main() {
    var a, b string = "foo", "bar"
    fmt.Println(a - b) // This line will cause a compilation error
}

// Error: invalid operation: a - b (operator - not defined on string)
  • In Go, the subtraction operator (-) cannot be used with strings. We can use the addition operator (+) for string concatenation but not the subtraction operator.
func main() {
    var a, b float64 = 87.96, 57.68
    fmt.Printf("%.2f", a-b)
}

// Output >> 30.28

Multiplication (*)

  • Multiplies both operands
func main() {
    var a, b int = 18, 9
    fmt.Println(a * b)
}

// Output >> 162

Division (/)

  • Returns the quotient when left operand is divided by right operand.
func main() {
    var a, b int = 44, 5
    fmt.Println(a / b)
}

// Output >> 8

Modulus (%)

  • Returns the remainder when left operand is divided by right operand.
func main() {
    var a, b int = 24, 7
    fmt.Println(a % b)
}

// Output >> 3

Increment (++)

  • Unary operator.

  • Acts upon a single operand to produce a new value.

  • Increments the value of the operand by one.

func main() {
    var i int = 1
    i++
    fmt.Println(i)
}

// Output >> 2

Decrement (--)

  • Unary operator.

  • Decrements the value of the operand by one.

func main() {
    var i int = 1
    i--
    fmt.Println(i)
}

// Output >> 0

Logical Operator

  • Used to determine the logic between variables or values.

  • Common logical comparisons -

    • Are two variables both true?

    • Does either of the two expressions evaluate to true?

AND (&&)

  • Returns true if both statements are true.

  • Returns false when either of the statements is false.

func main() {
    var x int = 45
    fmt.Println((x < 100) && (x < 200))
    fmt.Println((x < 300) && (x < 20))
}

/* Output >>
    true
    false
*/

OR (||)

  • Returns true if one of the statements is true.

  • Returns false when both of the statements are false

func main() {
    var x int = 10
    fmt.Println((x < 0) || (x < 100))
    fmt.Println((x < 0) || (x > 100))
}

/* Output >>
    true
    false
*/

NOT (!)

  • Unary operator

  • It reverses the result and returns false if the expression evaluates true and vice versa.

func main() {
    var x, y int = 10, 20
    fmt.Println(!(x > y))
    fmt.Println(!(true))
    fmt.Println(!(false))
}

/* Output
true
false
true
*/

Assignment Operators

Assign (=)

  • Assigns the left operand with the value of the right.

  • x = y

func main() {
    var x int = 10
    var y int
    y = x
    fmt.Println(y)
}

// Output: 10

Add and assign (+=)

  • Assigns left operand with the addition result

  • x += y means x = x + y

func main() {
    var x, y int = 10, 20
    x += y
    fmt.Println(x)
}

// output: 30

Subtract and assign (-=)

  • Assigns left operand with the subtraction result.

  • x -= y means x = x-y

func main() {
    var x, y int = 10, 20
    x -= y
    fmt.Println(x)
}

// Output : -10

Multiply and assign (*=)

  • Assigns left operand with the multiplication result.

  • x += y means x = x * y

func main() {
    var x, y int = 10, 20
    x *= y
    fmt.Println(x)
}

// Output : 200

Devide and assign quotient (/=)

  • Assigns left operand with the quotient of the division.

  • x /= y means x = x / y

func main() {
    var x, y int = 200, 10
    x /= y
    fmt.Println(x)
}

// Output: 20

Divide and assign modulus (%=)

  • Assigns left operand with the remainder of the division

  • x %= y means x = x % y

func main() {
    var x, y int = 20, 10
    x %= y
    fmt.Println(x)
}

// Output: 0

Bitwise Operators

Bitwise AND (&)

  • Takes two numbers as operands and does AND operation on every bit of two numbers.

func main() {
    var x, y int = 12, 25
    z := (x & y)
    fmt.Println(z)
}

// Output: 8

Bitwise OR (|)

  • Takes two numbers as operandsand does OR n every bit of two numbers.

func main() {
    var x, y int = 12, 25
    z := (x | y)
    fmt.Println(z)
}

// Output: 29

Bitwise XOR (^)

  • Takes two numbers as operands nd does XOR on every bit of two numbers.

  • The result of XOR is 1 if the two bits are opposite.

func main() {
    var x, y int = 12, 25
    z := (x ^ y)
    fmt.Println(z)
}

// Output: 21

Left shift (<<)

  • Shifts all bits towards left by a certain number of specified bits.

  • The bit position that have been vaceted by the left shift operator are filled with 0.

func main() {
    var x int = 212
    z := x << 1
    fmt.Println(z)
}

// Output: 424

Right shift (>>)

  • Shifts all bits towards right by a certain number of specified bits.

  • Excess bits shifted off to the right re discarded.

func main() {
    var x int = 212
    z := x >> 2
    fmt.Printf("%v", z)
}

// Output: 53

Control Flow

if-else

if condition {
    // Code to execute when the condition is true
}

Parantheses around the condition are optional.

func main() {
    var a string = "Happy"

    if a == "Happy" {
        fmt.Println(a)
    }
}

// Output: Happy
if condition {
    // Code to execute when the condition is true
} else {
    // Code to execute when the condition is false
}

Incorrext syntax

func main() {
    var fruit string = "Apple"

    if fruit == "Apple" {
        fmt.Println("Fruit is Apple")
    }
    else { // Error: 'else' should be on the same line as the closing brace of 'if'
        fmt.Println("Fruit is not Apple")
    }
}

Correct syntax

func main() {
    var fruit string = "Apple"

    if fruit == "Apple" {
        fmt.Println("Fruit is Apple")
    } else { 
        fmt.Println("Fruit is not Apple")
    }
}
if condition_1 {
    // Executes when condition_1 is true
} else if condition_2 {
    // Executes when condition_1 is false and condition_2 is true
} else if condition_3 {
    // Executes when condition_1 and condition_2 are false, and condition_3 is true
} else {
    // Executes when none of the above conditions are true
}
func main() {
    fruit := "grapes"

    if fruit == "apple" {
        fmt.Println("I love apples")
    } else if fruit == "orange" {
        fmt.Println("Oranges are not apple")
    } else {
        fmt.Println("no appetite")
    }
}

// Output: no appetite

Switch-case

Syntax

switch expression {
case value_1:
    // Executes when expression equals value_1
case value_2:
    // Executes when expression equals value_2
default:
    // Executes when no match is found
}
func main() {
    var i int = 100

    switch i {
    case 10:
        fmt.Println("i is 10")
    case 100, 200:
        fmt.Println("i is either 100 or 200")
    default:
        fmt.Println("i is neither 10, 100, nor 200")
    }
}

// Output: i is either 100 or 200
func main() {
    var i int = 800

    switch i {
    case 10:
        fmt.Println("i is 10")
    case 100, 200:
        fmt.Println("i is either 100 or 200")
    default:
        fmt.Println("i is neither 10, 100, nor 200")
    }
}

// Output: i is neither 10, 100, nor 200

fallthrough

  • The fallthrough keyword is used in switch-case to force the execution flow to fall through the successive case block.
func main() {
    var i int = 10

    switch i {
    case -5:
        fmt.Println("-5")
    case 10:
        fmt.Println("10")
        fallthrough
    case 20:
        fmt.Println("20")
        fallthrough
    default:
        fmt.Println("default")
    }
}

/* Output:
    10
    20
    default
*/

fallthrough use to continue executing the next case.

Switch with condition

  • Without mentioning expression after switch keywords

Syntax

switch {
case condition_1:
    // Execute when condition_1 is true
case condition_2:
    // Execute when condition_2 is true
default:
    // Execute when no condition is true
}
func main() {
    var a, b int = 10, 20

    switch {
    case a+b == 30:
        fmt.Println("equal to 30")
    case a+b <= 30:
        fmt.Println("less than or equal to 30")
    default:
        fmt.Println("greater than 30")
    }
}

// Output: equal to 30
  • Go uses an implicit break statement for each case. This is very different from languages like C or Java, where we explicitly write the break keyword.

Over here, a case block with the condition a+b == 30 was executed, because it is the first one in the order.

Looping with for loop

Loop is a sequence of instructions that is continually repeated until a certain condition is reached.

For loop syntax

for initialization; condition; post {
    // statements
}
func main() { 
   for i := 1; i <= 3; i++ {
        fmt.Println("Hello World")
    }
}

Q. Print the square of numbers till 5 from 1

func main() {
    for i := 1; i <= 5; i++ {
        fmt.Println(i * i)
    }
}

As initialization and post statements are optional, we can write the above for loop without initialization and post part.

func main() {
    i := 1
    for i <= 5 {
        fmt.Println(i * i)
        i++
    }
}

Infinite loop

If we skip the condition, then it will become infinite loop

func main() {
    sum := 0
    for {
        sum += 1 // repeated forever
    }
    fmt.Println(sum) // never reached
}
func main() {
    for {
        fmt.Println("Hello World!")
    }
}

Break and Continue

Break statement

  • The break statement ends the loop immediately when it is encountered.
func main() {
    for i := 1; i <= 5; i++ {
        if i == 3 {
            break
        }
        fmt.Println(i)
    }
}

/* Output:
1
2
*/

Continue statement

  • The continue statement skips the current iteration of loop and continues with the next iteration.
func main() {
    for i := 1; i <= 5; i++ {
        if i == 3 {
            continue
        }
        fmt.Println(i)
    }
}

/* Output:
1
2
4
5
*/

References

KodeKloud

0
Subscribe to my newsletter

Read articles from Arindam Baidya directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Arindam Baidya
Arindam Baidya