Logo
Published on

Hello World in Go - Your First Go Program

Authors

Hello World in Go - Your First Go Program

Every programming journey begins with "Hello, World!" In Go, this simple program introduces you to the language's fundamental concepts: packages, imports, functions, and the compilation process. Let's dive deep into writing, understanding, and expanding your first Go program.

The Classic Hello World

Basic Hello World

package main

import "fmt"

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

Running the Program

# Save as hello.go
go run hello.go

# Output: Hello, World!

Anatomy of a Go Program

Let's break down each component of our Hello World program:

1. Package Declaration

package main

Explanation:

  • Every Go file starts with a package declaration
  • main is a special package name for executable programs
  • Only main package can contain the entry point function
  • Other packages are used for libraries and modules

Examples:

package main      // Executable program
package utils     // Library package
package models    // Library package
package handlers  // Library package

2. Import Statement

import "fmt"

Explanation:

  • import brings in external packages
  • fmt (format) package provides I/O formatting functions
  • Standard library packages don't need module prefixes

Import Variations:

// Single import
import "fmt"

// Multiple imports (preferred)
import (
    "fmt"
    "os"
    "time"
)

// Aliased import
import f "fmt"

// Blank import (for side effects)
import _ "database/sql"

// Dot import (imports into current namespace)
import . "fmt"

3. Main Function

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

Explanation:

  • func keyword declares a function
  • main() is the entry point for executable programs
  • Function body is enclosed in curly braces {}
  • fmt.Println() prints text followed by a newline

Expanded Hello World Examples

Hello World with Variables

package main

import "fmt"

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

Hello World with User Input

package main

import (
    "fmt"
    "bufio"
    "os"
    "strings"
)

func main() {
    reader := bufio.NewReader(os.Stdin)
    
    fmt.Print("Enter your name: ")
    name, _ := reader.ReadString('\n')
    name = strings.TrimSpace(name)
    
    fmt.Printf("Hello, %s!\n", name)
}

Hello World with Command Line Arguments

package main

import (
    "fmt"
    "os"
)

func main() {
    args := os.Args
    
    if len(args) < 2 {
        fmt.Println("Hello, World!")
        return
    }
    
    name := args[1]
    fmt.Printf("Hello, %s!\n", name)
}

Usage:

go run hello.go
# Output: Hello, World!

go run hello.go Alice
# Output: Hello, Alice!

Hello World with Time

package main

import (
    "fmt"
    "time"
)

func main() {
    now := time.Now()
    hour := now.Hour()
    
    var greeting string
    switch {
    case hour < 12:
        greeting = "Good morning"
    case hour < 18:
        greeting = "Good afternoon"
    default:
        greeting = "Good evening"
    }
    
    fmt.Printf("%s, World! Current time: %s\n", 
        greeting, 
        now.Format("15:04:05"))
}

Compilation and Execution

Running vs Building

go run - Direct Execution

# Compiles and runs immediately
go run hello.go

# With multiple files
go run *.go

# With module path
go run github.com/user/repo/cmd/hello

go build - Create Executable

# Build executable
go build hello.go
# Creates: hello (Linux/macOS) or hello.exe (Windows)

# Build with custom name
go build -o myprogram hello.go

# Build for current directory
go build .

# Build with optimizations
go build -ldflags="-s -w" hello.go

Cross-Platform Compilation

# Build for Linux
GOOS=linux GOARCH=amd64 go build hello.go

# Build for Windows
GOOS=windows GOARCH=amd64 go build hello.go

# Build for macOS
GOOS=darwin GOARCH=amd64 go build hello.go

# Build for ARM64
GOOS=linux GOARCH=arm64 go build hello.go

Execution Examples

# After building
./hello              # Linux/macOS
hello.exe            # Windows

# Check file size
ls -lh hello
# Output: -rwxr-xr-x 1 user user 1.8M Sep  3 10:30 hello

Understanding Go Syntax

Code Formatting

Go enforces strict formatting rules through gofmt:

// Properly formatted Go code
package main

import "fmt"

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

Auto-formatting:

# Format single file
gofmt -w hello.go

# Format all Go files in directory
gofmt -w .

# Show differences without modifying
gofmt -d hello.go

Semicolons (Automatic Insertion)

// Go automatically inserts semicolons
package main

import "fmt"

func main() {
    fmt.Println("Hello")  // Semicolon automatically inserted
    fmt.Println("World")  // Semicolon automatically inserted
}

Braces Placement

// Correct - opening brace on same line
func main() {
    fmt.Println("Hello")
}

// Incorrect - will cause compilation error
func main()
{
    fmt.Println("Hello")
}

Common Variations and Patterns

Hello World Web Server

package main

import (
    "fmt"
    "net/http"
    "log"
)

func helloHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, World!")
}

func main() {
    http.HandleFunc("/", helloHandler)
    fmt.Println("Server starting on :8080")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

Hello World with JSON

package main

import (
    "encoding/json"
    "fmt"
    "log"
)

type Message struct {
    Text string `json:"text"`
    Time string `json:"time"`
}

func main() {
    msg := Message{
        Text: "Hello, World!",
        Time: "2025-09-03",
    }
    
    jsonData, err := json.Marshal(msg)
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Println(string(jsonData))
}

Hello World with Goroutines

package main

import (
    "fmt"
    "time"
)

func printHello(name string) {
    for i := 0; i < 3; i++ {
        fmt.Printf("Hello, %s! (%d)\n", name, i+1)
        time.Sleep(100 * time.Millisecond)
    }
}

func main() {
    go printHello("Goroutine")
    printHello("Main")
    
    // Wait for goroutine to finish
    time.Sleep(500 * time.Millisecond)
}

Error Handling in Hello World

Basic Error Handling

package main

import (
    "fmt"
    "os"
)

func main() {
    file, err := os.Open("hello.txt")
    if err != nil {
        fmt.Printf("Error: %v\n", err)
        return
    }
    defer file.Close()
    
    fmt.Println("File opened successfully!")
}

Creating Custom Errors

package main

import (
    "errors"
    "fmt"
)

func greet(name string) error {
    if name == "" {
        return errors.New("name cannot be empty")
    }
    
    fmt.Printf("Hello, %s!\n", name)
    return nil
}

func main() {
    if err := greet(""); err != nil {
        fmt.Printf("Error: %v\n", err)
    }
    
    greet("World")
}

Performance Analysis

Benchmarking Hello World

package main

import (
    "fmt"
    "testing"
)

func BenchmarkHelloWorld(b *testing.B) {
    for i := 0; i < b.N; i++ {
        fmt.Sprintf("Hello, World!")
    }
}

func BenchmarkHelloWorldPrint(b *testing.B) {
    for i := 0; i < b.N; i++ {
        fmt.Print("Hello, World!")
    }
}

Run benchmarks:

go test -bench=.
# Output: 
# BenchmarkHelloWorld-8           3000000    500 ns/op
# BenchmarkHelloWorldPrint-8      1000000   1500 ns/op

Memory Usage Analysis

# Build with debug info
go build -gcflags="-m" hello.go

# Profile memory usage
go tool compile -memprofile=mem.prof hello.go
go tool pprof mem.prof

Testing Hello World

Unit Test

// hello_test.go
package main

import (
    "testing"
    "io"
    "os"
    "strings"
)

func TestHelloWorld(t *testing.T) {
    // Capture stdout
    old := os.Stdout
    r, w, _ := os.Pipe()
    os.Stdout = w
    
    // Run the function
    main()
    
    // Restore stdout
    w.Close()
    os.Stdout = old
    
    // Read captured output
    output, _ := io.ReadAll(r)
    result := strings.TrimSpace(string(output))
    
    expected := "Hello, World!"
    if result != expected {
        t.Errorf("Expected %q, got %q", expected, result)
    }
}

Run tests:

go test
# Output: PASS

Industry Best Practices

Project Structure

hello-world/
├── main.go          # Main application
├── main_test.go     # Tests
├── go.mod           # Module definition
├── go.sum           # Dependency checksums
├── README.md        # Documentation
├── Makefile         # Build automation
└── .gitignore       # Git ignore rules

go.mod Example

module github.com/username/hello-world

go 1.21

require (
    github.com/stretchr/testify v1.8.4
)

Makefile

.PHONY: build test clean run

build:
	go build -o bin/hello main.go

test:
	go test -v

run:
	go run main.go

clean:
	rm -rf bin/

install:
	go install

Real-World Applications

CLI Tool Structure

package main

import (
    "flag"
    "fmt"
    "os"
)

var (
    name = flag.String("name", "World", "Name to greet")
    uppercase = flag.Bool("upper", false, "Use uppercase")
)

func main() {
    flag.Parse()
    
    greeting := fmt.Sprintf("Hello, %s!", *name)
    
    if *uppercase {
        greeting = strings.ToUpper(greeting)
    }
    
    fmt.Println(greeting)
}

Configuration-Based Hello World

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "os"
)

type Config struct {
    Message string `json:"message"`
    Name    string `json:"name"`
}

func main() {
    file, err := os.Open("config.json")
    if err != nil {
        log.Fatal(err)
    }
    defer file.Close()
    
    var config Config
    decoder := json.NewDecoder(file)
    if err := decoder.Decode(&config); err != nil {
        log.Fatal(err)
    }
    
    fmt.Printf("%s, %s!\n", config.Message, config.Name)
}