Category: Go Programming Language

  • Structures in Golang

    Structures

    structure, or struct, in Go is a user-defined data type that groups together related items of different types into a single type. Any real-world entity with a set of properties or attributes can be effectively represented as a struct. This concept is often compared to classes in object-oriented programming but serves as a lightweight alternative. Unlike classes, structs in Go do not support inheritance but do support composition. For instance, consider a Person having a name, age, and address. It makes sense to group these attributes into a single structure like this:

    Declaring a Structure:

    type Person struct {
        name    string
        age     int
        address string
    }

    Here, the type keyword is used to introduce a new type named Person, followed by the keyword struct, indicating that we are defining a structure. Inside the curly braces {}, the struct fields are listed with their names and corresponding data types.

    Compact Notation:

    Fields of the same type can be declared together, as shown in this example:

    type Person struct {
        name, address string
        age           int
    }

    Declaring and Initializing a Structure:

    To define a variable of a struct type, use the following syntax:

    var p Person

    This creates a variable p of type Person, initializing all fields to their zero values ("" for strings, 0 for integers, etc.). A struct can also be initialized with values using a struct literal:

    var p = Person{"Alice", 25, "New York"}

    Named Field Initialization:

    The name:value syntax allows initializing fields by name, skipping the order requirement:

    var p = Person{name: "Bob", age: 30}

    Uninitialized fields will automatically be set to their zero values.

    Example Program:

    package main
    
    import "fmt"
    
    // Define a struct
    type Person struct {
        name    string
        age     int
        address string
    }
    
    func main() {
        // Zero-value initialization
        var p Person
        fmt.Println(p)
    
        // Initializing with struct literal
        p1 := Person{"Alice", 25, "New York"}
        fmt.Println("Person1:", p1)
    
        // Named initialization
        p2 := Person{name: "Bob", age: 30}
        fmt.Println("Person2:", p2)
    
        // Uninitialized fields have zero value
        p3 := Person{name: "Charlie"}
        fmt.Println("Person3:", p3)
    }

    Output:

    { 0 }
    Person1: {Alice 25 New York}
    Person2: {Bob 30 }
    Person3: {Charlie 0 }

    Accessing Fields of a Struct:

    Fields of a struct are accessed using the dot (.) operator.

    Example Program:

    package main
    
    import "fmt"
    
    // Define the struct
    type Vehicle struct {
        brand, model string
        weight       float64
    }
    
    func main() {
        v := Vehicle{brand: "Tesla", model: "Model S", weight: 2100}
    
        // Access and display fields
        fmt.Println("Vehicle Brand:", v.brand)
        fmt.Println("Vehicle Model:", v.model)
    
        // Update a field value
        v.model = "Model X"
        fmt.Println("Updated Vehicle:", v)
    }

    Output:

    Vehicle Brand: Tesla
    Vehicle Model: Model S
    Updated Vehicle: {Tesla Model X 2100}

    Pointers to a Struct:

    Pointers in Go store the memory address of variables. Similarly, you can create pointers to structs.

    Example Program:

    package main
    
    import "fmt"
    
    // Define a struct
    type Book struct {
        title, author string
        price         float64
    }
    
    func main() {
        b := &Book{"Go Programming", "John Doe", 29.99}
    
        // Access fields via pointer
        fmt.Println("Title:", b.title)
        fmt.Println("Author:", b.author)
    }

    Output:

    Title: Go Programming
    Author: John Doe

    Additional Details and Benefits:

    1. Encapsulation: Structures group related data, simplifying management.
    2. Code Organization: They help organize complex data logically.
    3. Type Safety: Define types for fields, reducing type-related errors.
    4. Flexibility and Performance: Structures are efficient for memory and processing.
    Before: a = 10, b = 20
    Sum: 35
    After: a = 10, b = 20

    Nested Structure in Golang

    structure or struct in Go is a user-defined data type that enables grouping elements of various types into a single unit. Structs are particularly useful for representing real-world entities that have multiple attributes or fields. Go supports nested structures, where a structure is used as a field within another structure. This concept is also known as Nested Structure.

    Syntax:

    type struct_name_1 struct {
        // Fields of the structure
    }
    type struct_name_2 struct {
        variable_name struct_name_1
    }

    Example Program:

    // Golang program to demonstrate nested structures
    package main
    
    import "fmt"
    
    // Define a basic structure
    type Book struct {
        title  string
        author string
        year   int
    }
    
    // Define a nested structure
    type Library struct {
        collection Book
    }
    
    func main() {
    
        // Initialize the fields of the structure
        library := Library{
            collection: Book{"The Alchemist", "Paulo Coelho", 1988},
        }
    
        // Display the values
        fmt.Println("\nDetails of the Book in the Library")
        fmt.Println(library)
    }

    Output:

    Details of the Book in the Library
    {{The Alchemist Paulo Coelho 1988}}

    Example 2: Nested Structure with Multiple Fields

    // Golang program to demonstrate nested structures
    package main
    
    import "fmt"
    
    // Define a structure for Employee details
    type Employee struct {
        name   string
        dept   string
        tenure int
    }
    
    // Define a structure for Manager with nested Employee details
    type Manager struct {
        name      string
        project   string
        experience int
        teamLead  Employee
    }
    
    func main() {
    
        // Initialize the fields of the structure
        manager := Manager{
            name:      "Alice",
            project:   "AI Research",
            experience: 10,
            teamLead:  Employee{"Bob", "IT", 5},
        }
    
        // Display the values
        fmt.Println("Details of the Manager")
        fmt.Println("Manager's Name: ", manager.name)
        fmt.Println("Project: ", manager.project)
        fmt.Println("Experience: ", manager.experience)
    
        fmt.Println("\nDetails of the Team Lead")
        fmt.Println("Team Lead's Name: ", manager.teamLead.name)
        fmt.Println("Department: ", manager.teamLead.dept)
        fmt.Println("Tenure: ", manager.teamLead.tenure)
    }

    Output:

    Details of the Manager
    Manager's Name:  Alice
    Project:  AI Research
    Experience:  10
    
    Details of the Team Lead
    Team Lead's Name:  Bob
    Department:  IT
    Tenure:  5

    Anonymous Structure and Field in Golang

    In Go, structures (or structs) help group elements of various types into a single logical unit, making them excellent for representing real-world entities. Anonymous structures are unnamed and temporary, designed for one-time use. On the other hand, anonymous fields allow embedding fields without explicitly naming them.

    Syntax:

    variable := struct {
        field1 dataType1
        field2 dataType2 // Definition of Anonymous Structure
        // Additional fields as needed
    }{value1, value2}
    
    type StructName struct {
        dataType1
        dataType2 // Anonymous Fields
        // Additional anonymous fields
    }

    Example Code:

    package main
    
    import "fmt"
    
    // Student struct containing an anonymous structure and anonymous fields
    type Student struct {
        struct { // Embedded anonymous structure for personal data
            fullName   string
            rollNumber int
        }
        CGPA float64 // Regular field
    }
    
    func main() {
        // Initializing the struct with values for the anonymous structure and other fields
        learner := Student{
            struct {
                fullName   string
                rollNumber int
            }{
                fullName:   "John Doe",
                rollNumber: 67890,
            },
            CGPA: 4.0,
        }
    
        // Printing the values
        fmt.Println("Full Name:", learner.fullName)
        fmt.Println("Roll Number:", learner.rollNumber)
        fmt.Println("CGPA:", learner.CGPA)
    }

    Output:

    Full Name: Jane Smith
    Roll Number: 98765
    CGPA: 3.9
    Anonymous Fields

    Anonymous fields in Go are fields defined without explicit names, where their types act as their names. This approach is handy when the type itself conveys enough meaning.

    Syntax:

    type StructName struct {
        dataType1
        dataType2
        // Additional anonymous fields
    }

    Example:

    package main
    
    import "fmt"
    
    // Student struct using anonymous fields
    type Student struct {
        int     // Roll number (anonymous field)
        string  // Name (anonymous field)
        float64 // CGPA (anonymous field)
    }
    
    func main() {
        // Initializing the Student struct with anonymous fields
        learner := Student{54321, "Alice", 4.1}
    
        // Printing the values
        fmt.Println("Roll Number:", learner.int)
        fmt.Println("Name:", learner.string)
        fmt.Println("CGPA:", learner.float64)
    }

    Output:

    Roll Number: 54321
    Name: Alice
    CGPA: 4.1
  • Functions & Methods

    Functions in Go Language

    In Go, functions are segments of code designed to carry out specific tasks. They can be reused throughout the program to optimize memory usage, enhance code clarity, and save time. Functions may return a value to the caller or not, depending on their implementation.

    Syntax:

    func function_name(Parameter-list)(Return_type) {
        // function body...
    }

    Example:

    package main
    
    import "fmt"
    
    // add() takes two integers and returns their sum
    func add(x, y int) int {
        return x + y
    }
    
    func main() {
        sum := add(8, 12)
        fmt.Printf("Sum: %d", sum)
    }

    Output:

    Sum: 20
    Function Declaration

    In Go, functions are defined using the func keyword, followed by the function name, a parameter list, and an optional return type.

    Syntax:

    func function_name(Parameter-list)(Return_type) {
        // function body...
    }

    Example:

    func add(x, y int) int {
        return x + y
    }

    Output:

    marks are 500 or more

    Explanation:

    • func: Used to declare a function.
    • function_name: The name of the function, e.g., add.
    • Parameter-listx, y int are the parameters with their types.
    • Return_typeint specifies the return type.
    Function Calling

    To execute a function, use its name followed by any required arguments in parentheses. For instance, add(8, 12) invokes the function with the arguments 8 and 12.

    Example:

    sum := add(8, 12)
    fmt.Printf("The sum is: %d", sum)

    Output:

    // Go program to demonstrate
    // the use of nested if statements
    package main
    
    import "fmt"
    
    func main() {
    
       // Declare two variables
       var a int = 250
       var b int = 500
    
       // Check the first condition
       if a < 300 {
    
          // If condition1 is true,
          // check the nested condition
          if b < 600 {
    
             // Executes if both conditions are true
             fmt.Printf("a is less than 300 and b is less than 600\n")
          }
       }
    }
    Function Arguments

    Go allows two methods for passing arguments to functions: Call by Value and Call by Reference. By default, Go employs call by value, where argument values are copied, ensuring that modifications inside the function do not affect the original variables.

    1. Call by Value: In this approach, the argument values are passed as copies to the function. Any changes made to these values inside the function remain local to the function.

    Example:

    package main
    
    import "fmt"
    
    func add(x, y int) int {
        x = x + 5 // modifying x within the function
        return x + y
    }
    
    func main() {
        a := 10
        b := 20
        fmt.Printf("Before: a = %d, b = %d\n", a, b)
        total := add(a, b)
        fmt.Printf("Sum: %d\n", total)
        fmt.Printf("After: a = %d, b = %d\n", a, b)
    }

    Output:

    Before: a = 10, b = 20
    Sum: 35
    After: a = 10, b = 20

    2. Call by Reference: In this method, pointers are passed to the function, allowing modifications made inside the function to affect the original variables.

    Example:

    package main
    
    import "fmt"
    
    func add(x, y *int) int {
        *x = *x + 5 // modifying x via its memory address
        return *x + *y
    }
    
    func main() {
        a := 10
        b := 20
        fmt.Printf("Before: a = %d, b = %d\n", a, b)
        total := add(&a, &b)
        fmt.Printf("Sum: %d\n", total)
        fmt.Printf("After: a = %d, b = %d\n", a, b)
    }

    Output:

    value is 150

    Variadic functions in Go

    Variadic functions in Go allow you to pass a flexible number of arguments to a function. This capability is particularly helpful when the exact number of arguments is unknown beforehand. A variadic function accepts multiple arguments of the same type and can handle calls with any number of arguments, including none.

    Syntax:

    func functionName(parameters ...Type) ReturnType {
        // Code
    }

    Example:

    package main
    import "fmt"
    
    // Variadic function to calculate product
    func product(nums ...int) int {
        result := 1
        for _, n := range nums {
            result *= n
        }
        return result
    }
    
    func main() {
        fmt.Println("Product of 2, 3, 4:", product(2, 3, 4))
        fmt.Println("Product of 6, 7:", product(6, 7))
        fmt.Println("Product with no numbers:", product())
    }

    Output:

    Product of 2, 3, 4: 24
    Product of 6, 7: 42
    Product with no numbers: 1

    In the syntax above:

    • parameters ...Type denotes that the function can accept a flexible number of arguments of type Type.
    • Inside the function, these arguments are accessible as a slice.
    Using Variadic Functions

    When defining a variadic function, include the ellipsis (...) after the parameter name, followed by the type of the arguments. These arguments are processed as a slice within the function.

    Calling a Variadic Function

    A variadic function can be called with any number of arguments, even none. The arguments provided are handled as a slice.

    Example:

    package main
    import "fmt"
    
    func product(nums ...int) int {
        result := 1
        for _, n := range nums {
            result *= n
        }
        return result
    }
    
    func main() {
        fmt.Println("Product of 1, 2, 3:", product(1, 2, 3))
        fmt.Println("Product of 5, 10:", product(5, 10))
        fmt.Println("Product with no numbers:", product())
    }

    Output:

    Product of 1, 2, 3: 6
    Product of 5, 10: 50
    Product with no numbers: 1
    Combining Variadic Functions with Regular Parameters

    You can mix regular parameters with a variadic parameter in a single function. However, the variadic parameter must always come last in the parameter list.

    Example:

    package main
    import "fmt"
    
    // Function with both a regular parameter and a variadic parameter
    func displayMessage(message string, numbers ...int) {
        fmt.Println(message)
        for _, n := range numbers {
            fmt.Println("Value:", n)
        }
    }
    
    func main() {
        displayMessage("Values are:", 7, 8, 9)
        displayMessage("More values:", 15, 20)
        displayMessage("No values provided:")
    }

    Output:

    Values are:
    Value: 7
    Value: 8
    Value: 9
    More values:
    Value: 15
    Value: 20
    No values provided:

    Anonymous function in Go Language

    An anonymous function is a function that lacks a name. It is particularly useful when you need to create a function inline. In Go, anonymous functions can also form closures. These are also referred to as function literals.

    Syntax:

    func(parameter_list)(return_type) {
        // Code block
    
        // Use return statement if return_type is provided.
        // If return_type is absent, do not use the return statement.
        return
    }()

    Example:

    package main
    import "fmt"
    
    func main() {
        // Anonymous function
        func() {
            fmt.Println("Hello, World from Go!")
        }()
    }

    Output:

    Hello, World from Go!
    Assigning to a Variable

    Anonymous functions can be assigned to a variable. Once assigned, the variable behaves like a regular function and can be invoked.

    Syntax:

    for {
        // statements...
    }

    Example:

    // Go program demonstrating a for loop as a while loop
    package main
    
    import "fmt"
    
    func main() {
        x := 0
        for x < 4 {
            fmt.Println("Value of x:", x)
            x++
        }
    }

    Output:

    Value of x: 0
    Value of x: 1
    Value of x: 2
    Value of x: 3
    Passing Arguments

    Anonymous functions are capable of accepting arguments.

    Example:

    package main
    import "fmt"
    
    func main() {
        // Passing arguments in an anonymous function
        func(greeting string) {
            fmt.Println(greeting)
        }("Hello, Go Developers!")
    }

    Output:

    Hello, Go Developers!
    Passing as Arguments

    It is also possible to pass an anonymous function as an argument to another function.

    Example:

    package main
    import "fmt"
    
    // Passing an anonymous function as an argument
    func processStrings(fn func(a, b string) string) {
        fmt.Println(fn("Hello ", "Go "))
    }
    
    func main() {
        combine := func(a, b string) string {
            return a + b + "Developers!"
        }
        processStrings(combine)
    }

    Output:

    Hello Go Developers!
    Returning Anonymous Functions

    An anonymous function can also be returned from another function, allowing you to use it later.

    Example:

    package main
    import "fmt"
    
    // Function returning an anonymous function
    func createGreeting() func(first, second string) string {
        return func(first, second string) string {
            return first + second + "is awesome!"
        }
    }
    
    func main() {
        greet := createGreeting()
        fmt.Println(greet("Go ", "Language "))
    }

    Output:

    Go Language is awesome!

    The Go language reserves two functions for special purposes: main() and init().

    main() Function

    In Go, the main package is a unique package used with programs that are designed to be executable. This package contains the main() function, which is a crucial function that serves as the entry point of all executable programs. The main() function neither accepts any arguments nor returns a value. It is automatically invoked by the Go runtime, so there is no need to explicitly call it. Every executable program must include exactly one main package and one main() function.

    Example:

    // Go program demonstrating the
    // functionality of main() function
    
    // Defining the main package
    package main
    
    // Importing necessary packages
    import (
        "fmt"
        "math"
        "strings"
        "time"
    )
    
    // Main function
    func main() {
    
        // Performing square root operation
        numbers := []float64{16, 25, 36, 49, 64}
        for _, num := range numbers {
            fmt.Printf("Square root of %.0f: %.2f\n", num, math.Sqrt(num))
        }
    
        // Finding the substring index
        fmt.Println("Index of substring:", strings.Index("HelloWorld", "World"))
    
        // Displaying the current timestamp
        fmt.Println("Current Unix time:", time.Now().Unix())
    }

    Output:

    Square root of 16: 4.00
    Square root of 25: 5.00
    Square root of 36: 6.00
    Square root of 49: 7.00
    Square root of 64: 8.00
    Index of substring: 5
    Current Unix time: 1737138000
    init() Function

    The init() function in Go is another special function that, like main(), neither accepts arguments nor returns values. It exists in every package and is automatically invoked when the package is initialized. This function is implicitly declared and cannot be explicitly called or referenced from other parts of the program. Multiple init() functions can be defined within the same program, and they execute in the order they are declared. The execution order of init() functions across multiple files follows the lexical order of the filenames (alphabetical order). The primary purpose of the init() function is to initialize global variables or perform setup tasks that cannot be accomplished in the global scope.

    Example:

    // Go program demonstrating the
    // behavior of init() function
    
    // Defining the main package
    package main
    
    // Importing required package
    import "fmt"
    
    // Defining the first init() function
    func init() {
        fmt.Println("First init() function executed")
    }
    
    // Defining the second init() function
    func init() {
        fmt.Println("Second init() function executed")
    }
    
    // Main function
    func main() {
        fmt.Println("main() function executed")
    }

    Output:

    First init() function executed
    Second init() function executed
    main() function executed

    Defer Keyword in Golang

    In the Go programming language, defer statements postpone the execution of a function, method, or anonymous function until the surrounding function completes. In simpler terms, while the arguments of a deferred function or method call are evaluated immediately, the execution itself is deferred until the enclosing function returns. You can define a deferred function, method, or anonymous function by using the defer keyword.

    Syntax:

    // For a function
    defer func func_name(parameter_list Type) return_type {
        // Code
    }
    
    // For a method
    defer func (receiver Type) method_name(parameter_list) {
        // Code
    }
    
    // For an anonymous function
    defer func(parameter_list) (return_type) {
        // Code
    }()

    Key Points:

    1. The Go language allows multiple defer statements in the same program, and they execute in LIFO (Last-In, First-Out) order, as illustrated in Example 2.
    2. The arguments of defer statements are evaluated immediately when the statement is encountered, but the function itself executes only when the surrounding function returns.
    3. Defer statements are commonly used for tasks like closing files, closing channels, or handling program panics gracefully.

    Example:

    // Go program demonstrating the concept of defer statements
    package main
    
    import "fmt"
    
    // Function to calculate the difference
    func difference(a1, a2 int) int {
        res := a1 - a2
        fmt.Println("Difference:", res)
        return 0
    }
    
    // Function to display a message
    func greet() {
        fmt.Println("Welcome to Go programming!")
    }
    
    // Main function
    func main() {
    
        // Normal call to difference() function
        difference(100, 40)
    
        // Deferred call to difference() function
        defer difference(200, 50)
    
        // Calling greet() function
        greet()
    }

    Output:

    Difference: 60
    Welcome to Go programming!
    Difference: 150

    Methods in Golang

    Go methods are similar to functions but with a significant difference: they have a receiver argument that allows access to the receiver’s properties. The receiver can either be a struct type or a non-struct type, but both must be part of the same package. You cannot define methods for types from other packages or for built-in types like int or string, as the compiler will generate an error.

    Syntax:

    func (receiver_name Type) method_name(parameter_list) (return_type) {
        // Method implementation
    }

    Example:

    package main
    
    import "fmt"
    
    // Defining a struct
    type car struct {
        brand string
        year  int
    }
    
    // Defining a method with a struct receiver
    func (c car) details() {
        fmt.Println("Brand:", c.brand)
        fmt.Println("Year:", c.year)
    }
    
    func main() {
        // Creating an instance of the struct
        vehicle := car{brand: "Toyota", year: 2022}
    
        // Calling the method
        vehicle.details()
    }

    Output:

    Brand: Toyota
    Year: 2022
    Methods with Struct Type Receiver

    When defining a method, the receiver can be a struct type. The receiver is accessible within the method. The earlier example demonstrates this with a struct type receiver.

    Methods with Non-Struct Type Receiver

    Go supports defining methods with non-struct type receivers, provided the type and the method definition exist in the same package. However, you cannot define methods for types from another package (e.g., intstring).

    Example:

    package main
    
    import "fmt"
    
    // Creating a custom type based on float64
    type measurement float64
    
    // Defining a method with a non-struct receiver
    func (m measurement) double() measurement {
        return m * 2
    }
    
    func main() {
        value := measurement(3.5)
        result := value.double()
    
        fmt.Printf("Double of %.1f is %.1f\n", value, result)
    }

    Output:

    Double of 3.5 is 7.0
    Methods with Pointer Receiver

    In Go, methods can also have pointer receivers, enabling modifications to the original data. This capability is unavailable with value receivers.

    Syntax:

    func (receiver *Type) method_name(parameters...) return_type {
        // Code to modify data
    }

    Example:

    package main
    
    import "fmt"
    
    // Defining a struct
    type animal struct {
        species string
    }
    
    // Method with pointer receiver to modify data
    func (a *animal) rename(newSpecies string) {
        a.species = newSpecies
    }
    
    func main() {
        pet := animal{species: "Cat"}
    
        fmt.Println("Before:", pet.species)
    
        // Calling the method to rename
        pet.rename("Dog")
    
        fmt.Println("After:", pet.species)
    }

    Output:

    Before: Cat
    After: Dog
    Methods Accepting Both Pointer and Value

    In Go, methods can accept both value and pointer receivers. Depending on how the method is invoked, Go automatically handles the conversion between pointers and values.

    Example:

    package main
    
    import "fmt"
    
    type book struct {
        title string
    }
    
    // Method with pointer receiver
    func (b *book) setTitle(newTitle string) {
        b.title = newTitle
    }
    
    // Method with value receiver
    func (b book) displayTitle() {
        fmt.Println("Title:", b.title)
    }
    
    func main() {
        novel := book{title: "Untitled"}
    
        // Calling pointer receiver method with value
        novel.setTitle("1984")
        fmt.Println("After pointer method:", novel.title)
    
        // Calling value receiver method with pointer
        (&novel).displayTitle()
    }

    Output:

    After pointer method: 1984
    Title: 1984

    Difference Between Method and Function

    AspectMethodFunction
    Contains a receiverYesNo
    Allows same name with different typesYesNo
    Usable as a first-order objectNoYes
  • Control Statement in Go

    if, if-else, Nested-if, if-else-if

    Decision-making in programming is analogous to decision-making in real life. In programming, a piece of code executes when a specified condition is met. These constructs are often referred to as Control Flow Statements. In Go programming, control statements are employed to guide the flow of execution in the program based on specified conditions. They allow the program’s flow to advance and branch depending on the program’s state.

    The decision-making statements in Go programming include:

    if Statement

    The if statement is the simplest form of decision-making. It determines whether a specific block of code will execute, based on whether a given condition evaluates to true. If the condition is true, the corresponding block is executed; otherwise, it is skipped.

    Syntax:

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

    Example:

    // Go program to demonstrate
    // the usage of the if statement
    package main
    
    import "fmt"
    
    func main() {
    
       // Declare a local variable
       var num int = 450
    
       // Check the condition using if
       if num > 100 {
    
          // This block executes if
          // the condition is true
          fmt.Printf("num is greater than 100\n")
       }
    
       fmt.Printf("The value of num is: %d\n", num)
    }

    Output:

    num is greater than 100
    The value of num is: 450

    Time Complexity: O(1)
    Auxiliary Space: O(1)

    if…else Statement

    The if statement handles execution when a condition is true, but what if the condition is false? In such cases, the else statement provides an alternative block of code to execute.

    Syntax:

    if condition {
    
        // Executes this block if
        // the condition is true
    } else {
    
        // Executes this block if
        // the condition is false
    }

    Example:

    // Go program to demonstrate
    // the use of the if…else statement
    package main
    
    import "fmt"
    
    func main() {
    
       // Declare a local variable
       var marks int = 900
    
       // Check the condition using if
       if marks < 500 {
    
          // This block executes if the
          // condition evaluates to true
          fmt.Printf("marks are less than 500\n")
    
       } else {
    
          // This block executes if the
          // condition evaluates to false
          fmt.Printf("marks are 500 or more\n")
       }
    }

    Output:

    marks are 500 or more

    Time Complexity: O(1)
    Auxiliary Space: O(1)

    Nested if Statement

    In Go, nested if statements allow placing one if statement inside another. This enables checking multiple conditions sequentially.

    Syntax:

    if condition1 {
    
       // Executes if condition1 is true
    
       if condition2 {
    
          // Executes if condition2 is true
       }
    }

    Example:

    // Go program to demonstrate
    // the use of nested if statements
    package main
    
    import "fmt"
    
    func main() {
    
       // Declare two variables
       var a int = 250
       var b int = 500
    
       // Check the first condition
       if a < 300 {
    
          // If condition1 is true,
          // check the nested condition
          if b < 600 {
    
             // Executes if both conditions are true
             fmt.Printf("a is less than 300 and b is less than 600\n")
          }
       }
    }

    Output:

    a is less than 300 and b is less than 600

    Time Complexity: O(1)
    Auxiliary Space: O(1)

    if..else..if Ladder

    When multiple conditions need to be evaluated, the if..else..if ladder provides a way to do so. The conditions are evaluated sequentially, and as soon as one condition is satisfied, its corresponding block is executed. If none of the conditions are true, the final else block executes.

    Important Points:

    • An if statement can have zero or one else, which must come after any else if blocks.
    • An if statement can have zero to multiple else if blocks, which must appear before the else.
    • Once an else if condition is true, no further else if or else blocks are evaluated.

    Syntax:

    if condition_1 {
    
         // Executes if condition_1 is true
    
    } else if condition_2 {
    
        // Executes if condition_2 is true
    
    } else {
    
        // Executes if none of the conditions are true
    }

    Example:

    // Go program to demonstrate the
    // usage of the if..else..if ladder
    package main
    
    import "fmt"
    
    func main() {
    
       // Declare a variable
       var value int = 150
    
       // Evaluate conditions
       if value == 50 {
    
          // Executes if condition1 is true
          fmt.Printf("value is 50\n")
    
       } else if value == 100 {
    
          // Executes if condition2 is true
          fmt.Printf("value is 100\n")
    
       } else if value == 150 {
    
          // Executes if condition3 is true
          fmt.Printf("value is 150\n")
    
       } else {
    
          // Executes if none of the conditions are true
          fmt.Printf("value does not match any condition\n")
       }
    }

    Output:

    value is 150

    Time Complexity: O(1)
    Auxiliary Space: O(1)

    Loops in Go Language

    The Go programming language has only one type of loop: the for loop. It is a control structure that allows the repetition of a block of code a specific number of times. The for loop in Go can be used in various forms, as explained below:

    1. Simple for Loop

    This is similar to the for loops in languages like C, C++, Java, and C#.

    Syntax:

    for initialization; condition; post {
        // statements...
    }
    • Initialization: Executes before the loop starts (optional).
    • Condition: A boolean expression evaluated at the start of each iteration. If true, the loop continues; otherwise, it stops.
    • Post statement: Executed after each iteration of the loop.

    Example:

    // Go program demonstrating a simple for loop
    package main
    
    import "fmt"
    
    func main() {
        // Using a for loop to print a message 5 times
        for i := 0; i < 5; i++ {
            fmt.Println("Hello, Go!")
        }
    }

    Output:

    Hello, Go!
    Hello, Go!
    Hello, Go!
    Hello, Go!
    Hello, Go!
    2. Infinite for Loop

    for loop can run indefinitely by omitting all three components of the for loop.

    Syntax:

    for {
        // statements...
    }

    Example:

    // Go program demonstrating an infinite for loop
    package main
    
    import "fmt"
    
    func main() {
        for {
            fmt.Println("This will run forever")
        }
    }

    Output:

    This will run forever
    This will run forever
    This will run forever
    ... (repeats endlessly)
    3. for Loop as a while Loop

    for loop can act like a while loop by specifying only the condition.

    Syntax:

    for {
        // statements...
    }

    Example:

    // Go program demonstrating a for loop as a while loop
    package main
    
    import "fmt"
    
    func main() {
        x := 0
        for x < 4 {
            fmt.Println("Value of x:", x)
            x++
        }
    }

    Output:

    Value of x: 0
    Value of x: 1
    Value of x: 2
    Value of x: 3
    4. Using range with for Loop

    The range keyword allows iteration over arrays, slices, strings, maps, or channels.

    Syntax:

    for index, value := range collection {
        // statements...
    }

    Example:

    // Go program demonstrating range with an array
    package main
    
    import "fmt"
    
    func main() {
        items := []string{"Apple", "Banana", "Cherry"}
    
        for idx, fruit := range items {
            fmt.Printf("Index: %d, Fruit: %s\n", idx, fruit)
        }
    }

    Output:

    Index: 0, Fruit: Apple
    Index: 1, Fruit: Banana
    Index: 2, Fruit: Cherry
    5. Iterating Over Strings

    for loop can iterate over Unicode code points in a string using range.

    Syntax:

    for index, char := range str {
        // statements...
    }

    Example:

    // Go program demonstrating iteration over a string
    package main
    
    import "fmt"
    
    func main() {
        for i, c := range "GoLang" {
            fmt.Printf("Character: %c at Index: %d\n", c, i)
        }
    }

    Output:

    Character: G at Index: 0
    Character: o at Index: 1
    Character: L at Index: 2
    Character: a at Index: 3
    Character: n at Index: 4
    Character: g at Index: 5
    6. Iterating Over Maps

    The for loop can iterate over keys and values in a map using range.

    Syntax:

    for key, value := range map {
        // statements...
    }

    Example:

    // Go program demonstrating iteration over a map
    package main
    
    import "fmt"
    
    func main() {
        countries := map[string]string{
            "IN": "India",
            "US": "United States",
            "FR": "France",
        }
    
        for code, name := range countries {
            fmt.Printf("Code: %s, Country: %s\n", code, name)
        }
    }

    Output:

    Code: IN, Country: India
    Code: US, Country: United States
    Code: FR, Country: France
    7. Iterating Over Channels

    for loop can iterate over values sent through a channel until it is closed.

    Syntax:

    for item := range channel {
        // statements...
    }

    Example:

    // Go program demonstrating iteration over a channel
    package main
    
    import "fmt"
    
    func main() {
        ch := make(chan int)
    
        go func() {
            for i := 1; i <= 3; i++ {
                ch <- i * 10
            }
            close(ch)
        }()
    
        for val := range ch {
            fmt.Println("Received:", val)
        }
    }

    Output:

    Received: 10
    Received: 20
    Received: 30

    Switch Statement in Go

    In Go, a switch statement is a versatile branching construct that provides an efficient mechanism to direct execution based on the value or type of an expression. Go supports two primary types of switch statements:

    • Expression Switch
    • Type Switch

    Example:

    package main
    import "fmt"
    
    func main() {
        day := 3
        switch day {
        case 1:
            fmt.Println("Sunday")
        case 2:
            fmt.Println("Monday")
        case 3:
            fmt.Println("Tuesday")
        case 4:
            fmt.Println("Wednesday")
        case 5:
            fmt.Println("Thursday")
        default:
            fmt.Println("Invalid day")
        }
    }

    Output:

    switch optionalStatement; optionalExpression {
    case expression1:
        // Code block
    case expression2: // Expression Switch
        // Code block
    default:
        // Code block
    }
    
    switch variable := interfaceValue.(type) {
    case type1:
        // Code block
    case type2: // Type Switch
        // Code block
    default:
        // Code block
    }
    Expression Switch

    An Expression Switch evaluates a specific expression and transfers control to a matching case based on the result of the evaluation. If no expression is provided, the switch defaults to evaluating true.

    Syntax

    switch optionalStatement; optionalExpression {
    case expression1:
        // Code block
    case expression2:
        // Code block
    default:
        // Code block
    }
    • optionalStatement: An optional single statement, such as variable declaration.
    • optionalExpression: An optional expression. If omitted, it defaults to true.

    Example with Optional Statement

    Here, we define a variable day in the optional statement and use it in the switch evaluation:

    package main
    import "fmt"
    
    func main() {
        switch day := 2; day {
        case 1:
            fmt.Println("Sunday")
        case 2:
            fmt.Println("Monday")
        case 3:
            fmt.Println("Tuesday")
        case 4:
            fmt.Println("Wednesday")
        case 5:
            fmt.Println("Thursday")
        default:
            fmt.Println("Invalid day")
        }
    }

    Output:

    Monday

    Example with Optional Expression

    If no expression is provided, the switch assumes the expression is true. This enables the use of conditional logic in case statements.

    package main
    import "fmt"
    
    func main() {
        day := 5
    
        switch {
        case day == 1:
            fmt.Println("Sunday")
        case day == 2:
            fmt.Println("Monday")
        case day > 3:
            fmt.Println("End of Week")
        default:
            fmt.Println("Invalid day")
        }
    }

    Output:

    End of Week
    Type Switch

    A Type Switch determines the type of an interface value rather than its actual value. This is particularly helpful when working with variables of unknown or mixed types.

    Syntax

    switch variable := interfaceValue.(type) {
    case type1:
        // Code block
    case type2:
        // Code block
    default:
        // Code block
    }

    Example:

    package main
    import "fmt"
    
    func main() {
        var day interface{} = "Tuesday"
    
        switch v := day.(type) {
        case int:
            fmt.Printf("Day number: %d\n", v)
        case string:
            switch v {
            case "Sunday":
                fmt.Println("Start of the week")
            case "Tuesday":
                fmt.Println("Midweek day")
            default:
                fmt.Println("Another weekday")
            }
        default:
            fmt.Printf("Unsupported type: %T\n", v)
        }
    }

    Output:

    Midweek day
  • Fundamentals in Go

    Identifiers

    In programming, identifiers are used for naming purposes. Essentially, identifiers are user-defined names for program components. In the Go language, identifiers can represent variable names, function names, constants, statement labels, package names, or types.

    Example:

    package main
    import "fmt"
    
    func main() {
        var course = "Learn Go Programming"
    }

    In the example above, there are three identifiers:

    • main: The name of the package.
    • main: The name of the function.
    • course: The name of the variable.
    Rules for Defining Identifiers:

    To define valid Go identifiers, certain rules must be followed. Failing to adhere to these rules results in compile-time errors:

    1. The identifier name must start with a letter or an underscore (_). It may include letters (a-zA-Z), digits (0-9), and underscores (_).
    2. The identifier name cannot start with a digit.
    3. Identifiers are case-sensitive.
    4. Reserved keywords cannot be used as identifier names.
    5. While there is no maximum limit on identifier length, it is recommended to keep names between 4 and 15 characters for readability.

    Example:

    // Valid identifiers:
    _student23
    course
    course2023
    CourseName
    COURSE_NAME
    
    // Invalid identifiers:
    123course
    func
    package

    Predeclared Constants:
    truefalseiotanil

    Predeclared Types:
    intint8int16int32int64uintuint8uint16uint32uint64uintptrfloat32float64complex128complex64boolbyterunestringerror

    Predeclared Functions:
    makelencapnewappendcopyclosedeletecomplexrealimagpanicrecover

    • Blank Identifier (_): The underscore character _ is a special identifier used as an anonymous placeholder in declarations, assignments, or operands.
    • Exported Identifiers: An identifier is considered exported if it starts with an uppercase letter and is declared in the package block or as a variable, function, type, or method name within a package. These identifiers can be accessed outside the package.

    Example of Exported Identifiers:

    File: utilities.go

    // utilities.go
    
    package utilities
    
    // Exported variable
    var GreetingMessage = "Welcome to Go Utilities!"

    File: main.go

    // main.go
    
    package main
    
    import (
        "fmt"
        "path/to/yourproject/utilities"
    )
    
    // Exported variable
    var ApplicationName = "Go Identifier Tutorial"
    
    func main() {
        // Accessing exported identifier within the same file
        fmt.Println(ApplicationName)
    
        // Accessing exported identifier from another package
        fmt.Println(utilities.GreetingMessage)
    }

    Output:

    Go Identifier Tutorial
    Welcome to Go Utilities!

    Keywords or Reserved words are the words in a programming language that serve specific purposes or represent predefined functionalities. These words are restricted from being used as identifiers, such as variable names or function names. Using these reserved words as identifiers will lead to compile-time errors.

    Example:

    // Go program to demonstrate the use of keywords
    package main
    
    import "fmt"
    
    // Here, package, import, func, var are keywords
    func main() {
    
        // Using a valid identifier
        var message = "Hello, Go Language!"
    
        fmt.Println(message)
    
        // Attempting to use a reserved word as an identifier
        // will result in a compile-time error
        // var return = "Invalid Identifier"
    }

    Output:

    Hello, Go Language!

    Go language contains 25 keywords in total, as listed below:

    break       case       chan      const       continue
    default     defer      else      fallthrough for
    func        go         goto      if          import
    interface   map        package   range       return
    select      struct     switch    type        var

    Example:

    // Go program demonstrating the usage of keywords
    
    // The package keyword is used to specify the main package
    package main
    
    // The import keyword is used to include the "fmt" package
    import "fmt"
    
    // The func keyword is used to define a function
    func main() {
    
        // The var keyword is used to declare variables
        // These are valid identifiers: name, lang, and topic
        var name = "Learn Go Programming"
        var lang = "Go Language"
        var topic = "Keywords"
    
        fmt.Printf("Learning Platform: %s", name)
        fmt.Printf("\nProgramming Language: %s", lang)
        fmt.Printf("\nTopic: %s", topic)
    }

    Output:

    Learning Platform: Learn Go Programming
    Programming Language: Go Language
    Topic: Keywords

    Data Types in Go

    Data types in Go define the kind of data a variable can store. Go provides several categories of data types, which are:

    1. Basic Type: Includes numbers, strings, and booleans.
    2. Aggregate Type: Includes arrays and structs.
    3. Reference Type: Includes pointers, slices, maps, functions, and channels.
    4. Interface Type: Defines a method set.

    Here, we’ll delve into the Basic Data Types, further divided into:

    • Numbers
    • Booleans
    • Strings
    Numbers

    In Go, numbers are categorized into:

    Integers: Go supports both signed and unsigned integers in various sizes:

    Data TypeDescription
    int88-bit signed integer
    int1616-bit signed integer
    int3232-bit signed integer
    int6464-bit signed integer
    uint88-bit unsigned integer
    uint1616-bit unsigned integer
    uint3232-bit unsigned integer
    uint6464-bit unsigned integer
    intSame size as the machine’s word size
    uintSame size as the machine’s word size
    runeAlias for int32 representing Unicode
    byteAlias for uint8
    uintptrHolds pointer-sized unsigned integers

    Arithmetic operations like addition, subtraction, multiplication, division, and modulus are supported.

    Example:

    // Go program to demonstrate integers
    package main
    
    import "fmt"
    
    func main() {
        // Example with unsigned 8-bit integer
        var num1 uint8 = 200
        fmt.Println(num1, num1-50)
    
        // Example with signed 16-bit integer
        var num2 int16 = 10000
        fmt.Println(num2+500, num2-500)
    }

    Output:

    200 150
    10500 9500

    Floating-Point Numbers

    Go provides two types of floating-point numbers:

    Data TypeDescription
    float3232-bit IEEE 754 floating-point number
    float6464-bit IEEE 754 floating-point number

    Arithmetic operations like addition, subtraction, multiplication, and division are supported.

    Example:

    // Go program to illustrate floating-point numbers
    package main
    
    import "fmt"
    
    func main() {
        num1 := 18.75
        num2 := 41.35
    
        // Perform subtraction
        result := num2 - num1
    
        // Display result and type
        fmt.Printf("Result: %f\n", result)
        fmt.Printf("Type of result: %T\n", result)
    }

    Output:

    Result: 22.600000
    Type of result: float64

    Booleans: The boolean type represents one of two values: true or false. Boolean values are not implicitly or explicitly converted to other types.

    Example:

    // Go program to demonstrate booleans
    package main
    
    import "fmt"
    
    func main() {
        var flag1 = (5 > 3)  // true
        var flag2 = (5 < 3)  // false
    
        fmt.Println("Flag1:", flag1)
        fmt.Println("Flag2:", flag2)
        fmt.Printf("Type of flag1: %T\n", flag1)
    }

    Output:

    Flag1: true
    Flag2: false
    Type of flag1: bool

    Strings

    Strings in Go are immutable sequences of bytes. They support concatenation using the + operator.

    Example:

    // Go program to demonstrate strings
    package main
    
    import "fmt"
    
    func main() {
        // Define a string
        text := "Go Programming"
    
        // Print string length and value
        fmt.Printf("Length: %d\n", len(text))
        fmt.Printf("String: %s\n", text)
    }

    Output:

    Length: 14
    String: Go Programming

    String Concatenation

    Example:

    // Go program for string concatenation
    package main
    
    import "fmt"
    
    func main() {
        str1 := "Hello, "
        str2 := "World!"
    
        // Concatenate strings
        result := str1 + str2
        fmt.Println("Concatenated String:", result)
    }

    Output:

    Concatenated String: Hello, World!

    Constants- Go Language

    As the name CONSTANTS suggests, it means fixed or unchanging. Similarly, in programming, constants are values that, once defined, cannot be modified. Constants in Go can have various data types like integers, floating-point numbers, characters, or string literals.

    How to Declare Constants

    Constants are declared similarly to variables, but the const keyword is used as a prefix. Unlike variables, constants cannot be declared using the shorthand := syntax.

    Example:

    package main
    
    import "fmt"
    
    const Gravity = 9.8
    
    func main() {
        const Platform = "GoLang Basics"
        fmt.Println("Welcome to", Platform)
    
        fmt.Println("Gravity on Earth is", Gravity)
    
        const IsLearningFun = true
        fmt.Println("Is learning Go fun?", IsLearningFun)
    }

    Output:

    Welcome to GoLang Basics
    Gravity on Earth is 9.8
    Is learning Go fun? true
    Typed and Untyped Numeric Constants
    • Typed Constants behave like immutable variables and can interact only with values of the same type.
    • Untyped Constants behave like literals and can interact with similar types.

    Constants can be defined either with or without a type.

    Example:

    const untypedInt = 200
    const untypedFloat = 45.6
    
    const typedInt int = 200
    const typedFloat float64 = 45.6
    Types of Constants in Go
    1. Numeric Constants
    2. String Literals
    3. Boolean Constants

    1. Numeric Constants:

    Numeric constants are precise values. Since Go is a statically typed language, it does not allow mixing numeric types in operations. For instance, adding an int to a float64 is not allowed.

    Integer Constants: Integer constants can be written in:

    • Decimal (base 10)
    • Octal (base 8, prefixed with 0)
    • Hexadecimal (base 16, prefixed with 0x or 0X)

    Example:

    package main
    
    import "fmt"
    
    func main() {
        const comp = complex(5, 7) // 5 is real, 7 is imaginary
        fmt.Println("Complex Number:", comp)
        fmt.Println("Real Part:", real(comp))
        fmt.Println("Imaginary Part:", imag(comp))
    }

    Complex Constants: A complex constant consists of a real and an imaginary part, separated by a comma and enclosed within parentheses.

    Example:

    package main
    
    import "fmt"
    
    func main() {
        const comp = complex(5, 7) // 5 is real, 7 is imaginary
        fmt.Println("Complex Number:", comp)
        fmt.Println("Real Part:", real(comp))
        fmt.Println("Imaginary Part:", imag(comp))
    }

    Output:

    Value of Pi: 3.14159
    Scientific Notation: 123

    2. String Literals

    Go provides two types of string literals:

    1. Double quotes (" "): For plain strings with escape sequences.
    2. Backticks (` `): For raw string literals.

    Example:

    package main
    
    import "fmt"
    
    func main() {
        const greeting = "Hello, Go!"
        const rawString = `Line 1
    Line 2
    Line 3`
        fmt.Println(greeting)
        fmt.Println(rawString)
    }

    Output:

    Hello, Go!
    Line 1
    Line 2
    Line 3

    3. Boolean Constants

    Boolean constants represent true and false.

    Example:

    package main
    
    import "fmt"
    
    const IsEnabled = true
    
    func main() {
        type status bool
        var defaultStatus = IsEnabled
        var customStatus status = IsEnabled
        fmt.Println("Default Status:", defaultStatus)
        fmt.Println("Custom Status:", customStatus)
    }

    Output:

    Default Status: true
    Custom Status: true
    Defining Multiple Constants

    You can declare multiple constants in a single block using parentheses.

    Example:

    package main
    
    import "fmt"
    
    const (
        Language = "Go Programming"
        Version  = 1.19
        Open     = true
    )
    
    func main() {
        fmt.Println("Language:", Language)
        fmt.Println("Version:", Version)
        fmt.Println("Open Source:", Open)
    }

    Output:

    Language: Go Programming
    Version: 1.19
    Open Source: true
  • Introduction of Go-Lang

    Introduction

    Go is a procedural programming language. It was developed in 2007 by Robert Griesemer, Rob Pike, and Ken Thompson at Google, but it was officially released in 2009 as an open-source programming language. Programs in Go are constructed using packages, which enable efficient dependency management. The language also incorporates features that resemble dynamic languages, such as type inference (e.g., x := 42 is a valid declaration for a variable x of type int).

    Go is a statically typed, concurrent, garbage-collected programming language designed at Google and launched in 2009. Its simplicity, efficiency, and user-friendliness have made it a preferred choice for building scalable network services, web applications, and command-line tools.

    Concurrency in Go

    Go is well-regarded for its built-in support for concurrency, which enables multiple tasks to execute simultaneously. This is implemented through Goroutines and Channels, which allow efficient multitasking. This capability makes Go a strong contender for developing high-performance, scalable network services and solving computationally intensive problems.

    Garbage Collection

    Another significant feature of Go is its garbage collection, which manages memory automatically. By eliminating manual memory management, Go reduces the risk of memory leaks and bugs associated with improper memory handling.

    Introduction to Go (Golang)

    Go, often referred to as Golang, is an open-source language developed by Google in 2007. It is designed to be efficient, straightforward, and compatible with modern hardware architectures. This language is widely used for building large-scale distributed systems and performance-critical applications.

    Example:

    package main
    
    import "fmt"
    
    func main() {
        fmt.Println("Hello, Universe!")
    }

    Output:

    Hello, Universe!
    Getting Started with Go Programming

    To experiment with Go programming, you can use online IDEs like The Go Playground or Replit. To set up Go on your computer, you will need:

    1. Text Editor: Options include Notepad (Windows), VS Code, Emacs, etc.
    2. Go Compiler: Available as a binary installable for multiple operating systems.

    Example:

    package main
    
    import "fmt"
    
    func main() {
        fmt.Println("2 * 3 =", 2 * 3)
    }

    Output:

    2 * 3 = 6
    Syntax Explanation
    1. Package Declaration: The program starts with the package main declaration, indicating its entry point.
    2. Import Statement: External packages like fmt are imported to enhance functionality. The fmt package handles formatted I/O operations.
    3. Main Function: This is the program’s execution starting point.
    4. fmt.Println Function: A standard library function for printing output to the console.
    Why Choose Go?

    Go strikes a balance between the ease of dynamic languages and the performance of statically typed, compiled languages. It supports modern computing needs, including networked and multicore processing.

    Unique Design Choices in Go
    • No need for forward declarations or header files.
    • Reduced boilerplate via simple type derivation using :=.
    • No explicit type hierarchies.
    Advantages of Go
    1. Efficiency: Lightweight Goroutines consume less memory than threads (e.g., 2 KB vs. 1 MB).
    2. Concurrency: Ideal for multi-process applications.
    3. Rich Libraries: A comprehensive standard library supports diverse functionalities.
    4. Performance: Optimized for high-speed and low-latency operations.
    5. Simplicity: Easy to learn with minimal syntax.
    Disadvantages of Go
    1. Limited object-oriented features like inheritance.
    2. Lack of generics, which restricts code reusability.
    3. Immature standard library for specific needs, such as UI development.
    Popular Applications Built with Go
    1. Docker: For containerized application deployment.
    2. Kubernetes: Orchestrates containerized workloads.
    3. InfluxDB: An open-source time-series database.
    4. Netflix: Utilizes Go for parts of its backend systems.

    Basic Program

    “Hello, World!” is the foundational program in any programming language. Let’s write this basic program in the Go Language by following these steps:

    Step 1: Open the Go Compiler
    In Go, programs are saved with the .go extension, and they are UTF-8 encoded text files.

    Step 2: Begin with the package main Declaration

    package main

    Every Go program starts with a package declaration. Packages in Go serve the purpose of organizing and reusing code. There are two types of Go programs: executable and library programs. Executable programs can be run directly from the terminal, while library programs are packages containing reusable code.
    The main package indicates that the program is executable rather than a shared library. It signifies the entry point of the program and includes the main function.

    Step 3: Import the Required Package

    import (
        "fmt"
    )

    The import keyword is used to include external packages in your program. The fmt package, specifically, provides functions for formatted input/output operations.

    Step 4: Write the Code in the main Function
    Here’s how to structure your code to display “Hello, World!” in Go:

    func main() {
        fmt.Println("Hello, World from Go!")
    }

    In the above snippet:

    • func is the keyword used to define a function in Go.
    • main is the program’s entry point function. It doesn’t accept any parameters or return any values, and it is automatically invoked when you execute the program.
    • Println() is a function provided by the fmt package that prints the specified string to the console, followed by a new line.

    Step 5: Updated Example Code:

    // My First Go Program
    package main
    
    import "fmt"
    
    // Main function
    func main() {
        fmt.Println("Welcome to Go Programming!")
    }

    Output:

    Welcome to Go Programming!
  • Go (Golang) Tutorial Roadmap

    Introduction to Go (Golang)

    Overview of Go

    Go (also known as Golang) is an open-source, statically typed, compiled programming language developed by Google. It is designed for simplicity, performance, and scalability, making it ideal for cloud services, distributed systems, and backend development.

    Basic Go Program

    • Structure of a Go program
    • Writing and running a simple “Hello, World” program

    Go Language Fundamentals

    Identifiers

    • Naming rules and conventions in Go

    Data Types in Go

    • Basic data types: int, float, string, bool
    • Composite data types: arrays, slices, structs
    • Reference types: pointers, maps, channels

    Constants

    • Declaring constants using const
    • Typed vs untyped constants

    Control Statements in Go

    Conditional Statements

    • if statement
    • if-else statement
    • Nested if
    • if-else-if ladder

    Loops in Go

    • for loop
    • Infinite loops
    • Loop control using break and continue

    Switch Statement

    • Expression switch
    • Type switch

    Functions and Methods

    Functions in Go

    • Defining and calling functions

    Variadic Functions

    • Functions with variable number of arguments

    Anonymous Functions

    • Lambda-style functions

    Defer Keyword

    • Deferred function execution

    Methods in Go

    • Methods with receiver types

    Structures in Go

    Structures

    • Defining and using structs

    Nested Structures

    • Structs within structs

    Anonymous Structures and Fields

    • Inline struct definitions

    Arrays in Go

    Arrays

    • Declaring and initializing arrays

    Copying Arrays

    • Copying one array into another

    Slices in Go

    Slices Overview

    • Creating and using slices

    Slice Composite Literals

    • Slice initialization techniques

    Strings in Go

    Working with Strings

    • String declaration
    • Common string operations

    Pointers in Go

    Pointer Basics

    • Understanding pointers

    Passing Pointers to Functions

    • Call-by-reference behavior

    Pointer to Struct

    • Accessing struct fields using pointers

    Double Pointer

    • Pointer to pointer

    Comparing Pointers

    • Pointer comparison rules

    Object-Oriented Programming in Go

    OOP Concepts in Go

    • Structs as objects
    • Methods and interfaces

    Concurrency in Go

    Goroutines

    • Lightweight threads

    Channels

    • Communication between goroutines

    Unidirectional Channels

    • Send-only and receive-only channels

    Select Statement

    • Handling multiple channel operations

    Error Handling in Go

    Defer

    • Resource cleanup

    Error Handling

    • Using the error interface

    Custom Errors

    • Creating custom error types

    Error Wrapping

    • Wrapping and unwrapping errors

    Panic and Recover

    • Handling runtime panics

    First-Class Functions

    • Functions as values
    • Passing functions as arguments

    Reflection in Go

    Reflection

    • Inspecting types at runtime
    • reflect package usage

    File Handling in Go

    Reading Files

    • Reading file contents

    Writing Files

    • Writing data to files