Day-1: Basic programming concepts of Golang

Day-1: Basic programming concepts of Golang

Go Program Basic Configuration

Go Program ၏ basic structure သည် ရိုးရှင်းပြီး package statement, import statement and function statement တို့ဖြင့် စတင်ပါတယ်။

package main

import (
  "fmt"
)

func main() {
    fmt.Print("Hello", "World!")
}

Go မှာဆိုရင် package main declaration သည် executable program များအတွက် entry point အဖြစ်အသုံးပြုသော အထူး package တစ်ခုဖြစ်ပါသည်။ ၎င်းကို main ဆိုတဲ့ package မှ ပိုင်ဆိုင်ပြီး ယူသုံးမယ်လို့ သတ်မှတ်ပေးခြင်း ဖြစ်ပါသည်။ Every Go program တိုင်းတွင် standalone executable program တစ်ခုဖန်တီးဖို့ main ဆိုတဲ့ package တစ်ခု မဖြစ်မနေပါရှိရပါမည်။ ၎င်းမရှိဘဲ program ကို runnable executable အဖြစ် တည်ဆောက်၍မရပါ။

အဘယ်ကြောင့်ဆိုသော် main ဆိုတဲ့ package တွင် starting point of the program အဖြစ် လုပ်ဆောင်ရသည့် main() function ပါဝင်ရသောကြောင့် ဖြစ်သည်။

import statement က package များကို ထည့်သွင်းရန် အသုံးပြုပါတယ်။

fmt package က Go ရဲ့ standard library မှာပါဝင်ပြီး formatted I/O (ဥပမာ- console မှာ text ထုတ်ပြခြင်း) ကို လုပ်ဆောင်ပေးသည်။

func main() ကတော့ Program ရဲ့ main function ဖြစ်ပြီး execution စတင်မဲ့နေရာ starting point of the program ဖြစ်ပါတယ်။ Program တစ်ခုမှာဆိုရင် package main နဲ့ main() function မပါခဲ့ရင် program ဟာ standalone executable အဖြစ် compile လုပ်လို့မရပါဘူး။

ပထမဦးဆုံး main.go ဆိုတဲ့ file တစ်ခုကို create လုပ်ပြီး Hello World ဆိုတဲ့ စာသားကို print ထုတ်ကြည့်ပါမယ်

aungaung@drlinuxer-x14:~/go$ vi main.go
package main

import (
  "fmt"
)

func main() {
    fmt.Print("Hello", "World!")
}

ပြီးရင် အခြေခံဖြစ်သည့် Print, Println and Printf တို့ရဲ့ ခြားနားချက်ကို ကြည့်ကျမယ်

Print က Arguments တွေဖြစ်တဲ့ “Hello“ and “World“ ကြားမှာ space မပါဖူး/ output ကို new line တစ်ခုအနေနဲ့ မထုတ်ပြဖူး/ low level output အနေဖြင့် ရိုးရိုးပဲထုတ်ပြတယ်/

aungaung@drlinuxer-x14:~/go$ cat main.go
package main

import (
  "fmt"
)

func main() {
    fmt.Print("Hello", "World!")
}

Println က Arguments တွေဖြစ်တဲ့ “Hello“ and “World“ ကြားမှာ space ထည့်ပေးတယ်/ output ကို new line တစ်ခုအနေနဲ့ ထုတ်ပြတယ်/ Debugging လုပ်တဲ့အခါမှာ သုံးတယ်

aungaung@drlinuxer-x14:~/go$ cat main.go
package main

import (
  "fmt"
)

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

Printf ကတော့ formatted output ကိုပြုလုပ်ရာတွင် format specifiers များကို အသုံးပြုပါသည်။ ၎င်းကို % ဖြင့် စတင်အသုံးပြုပါသည်။ Format specifiers များသည် output ၏ data type နှင့် presentation ကို ဖော်ပြရန်အသုံးပြုသည့် placeholder များဖြစ်သည်။

fmt.Print("Hello", "World")  // Output: HelloWorld (no space)
fmt.Println("Hello", "World") // Output: Hello World (space between, newline after)
fmt.Printf("Hello %s, Age: %d\n", "Alice", 30) // Output: Hello Alice, Age: 30 (formatted output with newline)
package main

import "fmt"

func main() {
    // Variables of different types
    name := "Alice"
    age := 30
    height := 5.7
    isActive := true
    hexVal := 255
    binVal := 5
    unsignedVal := 4000000000
    ptr := &name
    char := 'A'

    // Printing various data types using format specifiers

    // String (%s)
    fmt.Printf("Name: %s\n", name) // Prints: Alice

    // Integer (%d)
    fmt.Printf("Age: %d years old\n", age) // Prints: 30 years old

    // Floating point with precision (%f or %.2f)
    fmt.Printf("Height: %.2f meters\n", height) // Prints: 5.70 meters

    // Boolean (%t)
    fmt.Printf("Active: %t\n", isActive) // Prints: true

    // Hexadecimal (lowercase) (%x)
    fmt.Printf("Hexadecimal value (lowercase): %x\n", hexVal) // Prints: ff

    // Hexadecimal (uppercase) (%X)
    fmt.Printf("Hexadecimal value (uppercase): %X\n", hexVal) // Prints: FF

    // Pointer (%p)
    fmt.Printf("Pointer address: %p\n", ptr) // Prints: memory address of 'name'

    // Character (rune) (%c)
    fmt.Printf("Character: %c\n", char) // Prints: A

    // Scientific notation (lowercase) (%e)
    fmt.Printf("Scientific notation (lowercase): %e\n", height) // Prints: 5.700000e+00

    // Scientific notation (uppercase) (%E)
    fmt.Printf("Scientific notation (uppercase): %E\n", height) // Prints: 5.700000E+00

    // Binary (%b)
    fmt.Printf("Binary value: %b\n", binVal) // Prints: 101 (binary of 5)

    // Unsigned decimal (%u)
    fmt.Printf("Unsigned decimal: %u\n", unsignedVal) // Prints: 4000000000

    // Quoted string (%q)
    fmt.Printf("Quoted string: %q\n", name) // Prints: "Alice"

    // Literal percent sign (%%)
    fmt.Printf("Literal percent sign: %%\n") // Prints: %

    // Default format (%v)
    fmt.Printf("Default format: %v\n", age) // Prints: 30
}

Summary of Common Format Specifiers:

  • %d - Integer (decimal)

  • %s - String

  • %f - Floating point

  • %v - Default format

  • %t - Boolean

  • %x - Hexadecimal (lowercase)

  • %X - Hexadecimal (uppercase)

  • %p - Pointer (memory address)

  • %c - Character (rune)

  • %e - Scientific notation (lowercase)

  • %E - Scientific notation (uppercase)

  • %b - Binary

  • %u - Unsigned decimal

  • %q - Single-quoted character literal

  • %% - Literal percent sign

Go တွင် Format specifiers များသည် အချက်အလက်များကို မည်သို့ပြသရမည်ဆိုတာကို သတ်မှတ်ရန် အသုံးပြုသည်။ ဥပမာအားဖြင့် numbers, strings, or other types of data များကို ပြသရန် လိုအပ်တဲ့ format ပုံစံဖြင့် သတ်မှတ်နိုင်ပါတယ်။

Key Differences of print, println and printf

Featureprintprintlnprintf
Adds spaces?No (does not automatically add spaces between arguments)Yes (adds a space between arguments)Depends (you specify the format, spaces added based on format)
Adds a newline?No (does not automatically add a newline)Yes (adds a newline at the end)No (newline added only if specified in the format string using \n)
UsageLow-level output: Useful for basic printing without formattingQuick debugging: Simpler, quick output with automatic newlineFormatted output: Allows detailed formatting with specifiers like %d, %s, etc.

Running a Go Program

go run main.go

go run: အဆိုပါ command က source code ကို compile လုပ်ပြီး binary အဖြစ် တိုက်ရိုက် run လုပ်ပါသည်။ ဒါပေမယ့် executable file ကို ထုတ်မပေးဘူး။ ဒါကို testing နှင့် development အတွက် အသုံးပြုတယ်။

Building a Go Program

go build main.go

go build: အဆိုပါ command က source code ကို compile လုပ်ပြီး လက်ရှိ directory အောက်တွင် (Linux မှာ main သို့မဟုတ် Windows မှာ main.exe) ဆိုတဲ့ executable file တစ်ခု ဖြစ်လာစေပါသည်။ Build လုပ်ထားတဲ့ file ကို Go runtime မလိုဘဲ တိုက်ရိုက် run လုပ်နိုင်တယ်။


Go Language တွင် Package Import လုပ်ခြင်း

Go Programming Language မှာ package များကို Import လုပ်ခြင်းဆိုတာ program ထဲမှာ external or standard library များကို ထည့်သွင်းခြင်းဖြစ်ပါတယ်။ ဒါကိုလုပ်တဲ့အတွက် program ရဲ့ စွမ်းဆောင်ရည်ကို တိုးမြှင့်ပြီး code များကို ပြန်လည်အသုံးပြုနိုင်မှာဖြစ်ပါတယ်။

Go packages ဆိုသည်မှာ ဆက်စပ်နေသည့် functions, types, နှင့် variables တွေကို စုစည်းထားသည့် module များဖြစ်သည်။ ၎င်းတို့က developers များအား ၎င်းတို့၏ code ကို အစိတ်အပိုင်းလိုက် စနစ်တကျ စီမံခန့်ခွဲရန်နှင့် ရှင်းလင်းပြတ်သားစွာ ရေးသားရန် ကူညီပေးသည်။

Syntax: Package များကို import keyword ကို အသုံးပြုပြီး Import လုပ်ပါသည်။

import "fmt"

Lab-1,

package main

import "fmt"

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

Multiple Imports: အချို့သော အချိန်များတွင် package များကို တစ်ခါတည်း multiple import လုပ်နိုင်ပြီး parentheses () ဖြင့် အသုံးပြုရပါသည်။

import (
    "fmt"
    "math"
)

Lab-2,

package main

import (
    "fmt"
    "math"
)

func main() {
    fmt.Println("Using Multiple Imports in Go")
    number := 16.0
    fmt.Printf("The square root of %.2f is %.2f\n", number, math.Sqrt(number))
}

Alias Imports: package များကို အမည်ပြောင်း၍ Import လုပ်နိုင်ခြင်း

import m "math"

Lab-3,

package main

import (
    m "math"
    "fmt"
)

func main() {
    number := 25.0
    fmt.Printf("The square root of %.2f is %.2f\n", number, m.Sqrt(number))
}

Blank Identifier _: Go တွင်၊ Blank Identifier (_) သည် values များကို စွန့်ပစ်ရန် သို့မဟုတ် သင်မလိုအပ်သောအခါတွင် တန်ဖိုးများကို အသုံးမပြုရန် အသုံးပြုသည့် special identifier တစ်ခုဖြစ်သည်။ ၎င်းသည် သင့် code တွင် မလိုလားအပ်သော values များကို မလိုအပ်ဖူးဟု သင်ခံစားရသောအခါ ၎င်းတို့ကို ရှောင်ရှားရန် ကူညီပေးသည်။

Discarding Return Values ( Return Values များကို စွန့်ပစ်ခြင်း)

Go တွင် တစ်ခုထက်ပိုသော return values များရှိသည့် functions တွေကို အသုံးပြုတဲ့အခါ တစ်ခုတည်းသော value ကို အသုံးပြုရန်နှင့် အခြား values များကို discard စွန့်ပစ်ရန် Blank Identifier _သုံးသည်။

package main

import "fmt"

// Function that returns a name and an age
func getDetails() (string, int) {
    return "Alice", 30
}

func main() {
    name, _ := getDetails()  // Discarding the second value (age)
    fmt.Println(name)         // Prints: "Alice"
}

getDetails() function မှ string နှင့် integer တန်ဖိုးနှစ်ခု return ပြန်ပါတယ်။

ဒါပေမယ့် main() function မှာ age ကို အသုံးမပြုချင်လျှင် _ ကို အသုံးပြု၍ age ကို လွှတ်ပစ်ခဲ့ပြီး name ကိုသာ အသုံးပြုထားပါတယ်။

Importing Packages for Side Effects

Go မှာ package တစ်ခုကို import လုပ်တဲ့အခါ ထို package မှတစ်ဆင့် side effect အတွက်သာ အသုံးပြုလိုတဲ့အခါ Blank Identifier (_) ကို သုံးပါတယ်။ ဆိုလိုသည် မှာ သင့် code တွင် တိုက်ရိုက်အသုံးမပြုရတဲ့ package များကို import လုပ်နိုင်ပြီး၊ init function ကို အလုပ်လုပ်စေဖို့အတွက် သုံးနိုင်ပါတယ်။

package main

import (
    "database/sql"                  // MySQL Database ကိုသုံးဖို့ Go SQL Package
    _ "github.com/go-sql-driver/mysql" // MySQL Driver ကို Import လုပ်ခြင်း (side effects အတွက်)
    "fmt"
)

func main() {
    // MySQL Database ကို connect လုပ်
    db, err := sql.Open("mysql", "user:password@tcp(localhost:3306)/dbname")
    if err != nil {
        fmt.Println("Error connecting to the database:", err)
        return
    }
    defer db.Close()

    fmt.Println("Connected to the database successfully!")
}

Package: "database/sql"

"database/sql" package သည် Go programming မှာ database နှင့်ဆက်သွယ်ရန် Interface များကို ပံ့ပိုးပေးပါတယ်။ ဒီ package ထဲမှာ Database connection, queries, transactions စသည်တို့ကို သုံးနိုင်ဖို့ function များပါဝင်ပါတယ်။ ဒါဟာ MySQL ကဲ့သို့သော သီးခြား database တစ်ခုကို အသုံးပြုရန်အတွက် သင်သည် "database/sql" နှင့် တွဲဖက်အသုံးပြုနိုင်သော driver တစ်ခု လိုအပ်ပါသည်။

Package: "github.com/go-sql-driver/mysql"

_ "github.com/go-sql-driver/mysql" သည် MySQL Driver ကို import လုပ်ထားခြင်းဖြစ်သည်။ Blank Identifier (_) ကို အသုံးပြုထားတာကြောင့် ဒီ driver package ကို သင့် code တစ်ခုလုံးမှာ တိုက်ရိုက်အသုံးမပြုသော်လည်း init() function ကို အလုပ်လုပ်စေပါတယ်။ init() function သည် Driver ကို "database/sql" package နဲ့အတူ register လုပ်ပေးပါတယ်။

How Does It Work?

Go မှာ package တစ်ခုကို import လုပ်တဲ့အခါ ထို package ထဲမှာရှိတဲ့ init() function ကို အလိုအလျောက် run ပေးပါတယ်။ MySQL Driver package ထဲမှာ init() function ပါပြီးသားဖြစ်ပြီး၊ ဒီ function က MySQL Driver ကို "database/sql" package နဲ့ပတ်သက်စေပါတယ်။ သင့် code မှာ Driver ကို တိုက်ရိုက်သုံးမနေပါက Go Compiler က "unused import" error မပေးဘဲ ကုဒ်အလုပ်လုပ်စေပါတယ်။

Importing for Side Effects

Side Effects ဆိုတာ Go တွင် package တစ်ခုကို import လုပ်လိုက်တဲ့အခါ၊ အလိုအလျောက် ဖြစ်ပေါ်လာတဲ့ actions တွေကို ဆိုလိုပါတယ်။ ဥပမာအားဖြင့် variable များကို initialize လုပ်ခြင်း သို့မဟုတ် configuration များကို register လုပ်ခြင်း ကဲ့သို့သော အလုပ်များကို အလိုအလျောက် လုပ်ဆောင်ပေးတာကို ဆိုလိုတာပါ။

ဤကိစ္စတွင် MySQL Driver ကို database/sql နဲ့အတူသုံးဖို့ side effect of the import တစ်ခုအနေဖြင့် register လုပ်ပေးခဲ့တာဖြစ်ပါတယ်။

Discarding Values in for Loop (for Loop တွင် Value ကို စွန့်ပစ်ခြင်း)

Go တွင် collection တစ်ခုကို iterate လုပ်တဲ့အခါ index သို့မဟုတ် value တစ်ခုကို လိုအပ်ရင် Blank Identifier (_) ကိုအသုံးပြုနိုင်ပါတယ်။ အခြားတန်ဖိုးများကို Blank Identifier (_) ဖြင့် discard စွန့်ပစ်နိုင်ပါသည်။

package main

import "fmt"

func main() {
    names := []string{"Alice", "Bob", "Charlie"}

    // index ကို discard လုပ်ပြီး, value (name) ကိုသာ အသုံးပြုပါတယ်
    for _, name := range names {
        fmt.Println(name)  // "Alice", "Bob", "Charlie" တို့ကို ထုတ်ပေးမည်
    }
}

for _, name := range names မှာ _ ကို အသုံးပြု၍ index ကို discard စွန့်ပစ်ပြီး name ကိုသာ အသုံးပြုထားပါတယ်။ အဆိုပါ loop မှာ names list ၏ value တွေကိုသာ အသုံးပြုသွားပြီး index ကို discard ပြုလုပ်သွားခဲ့သည်။

Discarding Errors (Error ကို discard စွန့်ပစ်ခြင်း)

တစ်ခါတစ်ရံတွင် သင်သည် error တစ်ခုကို ချက်ချင်း သို့မဟုတ် လုံးဝ ကိုင်တွယ်ရန် မလိုအပ်ပေ။ သင်သည် Blank Identifier (_) ကိုအသုံးပြု၍ error value ကို discard စွန့်ပစ်နိုင်သည်။

package main

import (
    "fmt"
    "os"
)

func main() {
    file, err := os.Open("example.txt") // ဖိုင်ကို ဖွင့်ဖို့ ကြိုးစားမယ်
    if err != nil {                     // Error ဖြစ်ပေါ်မယ်ဆိုရင်
        fmt.Println("Error occurred:", err)
        return
    }
    defer file.Close() // ဖိုင်ကို ပြီးရင်ပြန်ပိတ်မယ်
    fmt.Println("File opened successfully!")
}

os.Open("example.txt") သည် ဖိုင်တစ်ခု ဖွင့်ဖို့ကြိုးစားပါတယ်။ Error မရှိရင်: file variable ထဲမှာ file နဲ့ဆက်သွယ်မှုကို ထားပေးမယ်။ Error ရှိရင်: err variable ထဲမှာ error message ကို သိမ်းပေးမယ်။

err != nil ဆိုတာကတော့ Error Checking လုပ်တဲ့ logic ပါ။ Error ရှိရင် fmt.Println("Error occurred:", err) က error ကို console မှာပြပေးမယ်။ Error မရှိရင် fmt.Println("File opened successfully!") ထွက်ပြောမယ်။

Standard Library and Third-Party Packages: Go program တစ်ခုတွင် standard နှင့် third-party packages များကို အတူပေါင်းစပ်နိုင်သည်။ Third-party package များကို go get command ဖြင့် ရယူပြီး project ထဲတွင် ပေါင်းထည့်ရမည်။

Lab-5,

package main

import (
    "fmt"
    "github.com/fatih/color"
)

func main() {
    fmt.Println("Hello, Go Modules!")
    color.Green("This is a green message using the Fatih Color package!")
}

Summary Table of Commands:

CommandDescription
cat go.modShows the project's direct dependencies.
cat go.sumShows all dependencies (direct and indirect).
go list -m allLists all modules (dependencies).
ls $GOPATH/pkg/modDisplays the cached downloaded modules.

Custom Packages: Custom Package ဆိုတာ Go source file များကို အစုလိုက် အဖွဲ့လိုက် စုပေါင်းထားပြီး အမည်တစ်ခုအောက်တွင် စီစဉ်ထားသော အဖွဲ့အစည်းတစ်ခုဖြစ်သည်။ Custom packages တွင် functions, types, constants, နှင့် variables များပါဝင်နိုင်ပြီး ၎င်းတို့ကို အချို့သော file များနှင့် project များအတွင်း ပြန်လည်အသုံးပြုနိုင်သည်။

  • math package: Go မှ built-in ဖြစ်ပြီး ပြန်လည်အသုံးပြုနိုင်သော သင်္ချာဆိုင်ရာ functions များကို ပေးသည်။

  • calculator package: ကိုယ်ပိုင် package တစ်ခုအနေဖြင့် Add, Subtract စသည့် function များကို project ၏ အစိတ်အပိုင်းအမျိုးမျိုးတွင် ပြန်လည်အသုံးပြုနိုင်ရန် ပါဝင်ထားသည်။

Lab-6,

root directory is my_go_project

Create a new directory called calculator under your project root directory.

aungaung@drlinuxer-x14:~/my_go_project$ pwd
/home/aungaung/my_go_project
mkdir calculator

Inside the calculator directory, create a file math.go with the following content

package calculator

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

func Multiply(a, b int) int {
    return a * b
}

Create a file main.go in the root directory.

Import and use the calculator package in main.go

package main

import (
    "fmt"
    "my_go_project/calculator" // Replace "your_project" with the actual module name
)

func main() {
    fmt.Println("Using a custom package:")
    sum := calculator.Add(10, 5)
    product := calculator.Multiply(10, 5)

    fmt.Printf("Sum: %d, Product: %d\n", sum, product)
}

Final Custom Packages File Structure

Why Use Custom Packages?

Code Reusability: Write code once and reuse it in multiple places without duplication.

Better Readability: Organize related functions and types together, making your code easier to read and understand.

Scalability: Manage larger projects by splitting code into smaller, logical units.

Testing: Test packages independently, improving overall code quality.