DEV Community

karoon sillapapan
karoon sillapapan

Posted on

Go Hello World Project with Best Practices

Project Structure:

hello-world-app/
├── go.mod
├── main.go
├── internal/
│   └── greeting/
│       └── greeting.go
└── README.md
Enter fullscreen mode Exit fullscreen mode

1. Initialize the module (run this first):

mkdir hello-world-app
cd hello-world-app
go mod init github.com/yourusername/hello-world-app
Enter fullscreen mode Exit fullscreen mode

2. go.mod (automatically created)

module github.com/yourusername/hello-world-app

go 1.21
Enter fullscreen mode Exit fullscreen mode

3. main.go

package main

import (
    "fmt"
    "log"

    "github.com/yourusername/hello-world-app/internal/greeting"
)

func main() {
    // Simple hello world
    fmt.Println("Hello, World!")

    // Using our custom package
    message := greeting.Generate("Go Developer")
    fmt.Println(message)

    // Demonstrating error handling
    personalizedMsg, err := greeting.Personalized("Alice", "Go")
    if err != nil {
        log.Printf("Error: %v", err)
        return
    }
    fmt.Println(personalizedMsg)
}
Enter fullscreen mode Exit fullscreen mode

4. internal/greeting/greeting.go

// Package greeting provides functionality for generating greeting messages.
// Following Go conventions: package comment starts with "Package packagename"
package greeting

import (
    "fmt"
    "strings"
)

// Generate creates a simple greeting message.
// Function comments start with the function name.
func Generate(name string) string {
    if name == "" {
        name = "World"
    }
    return fmt.Sprintf("Hello, %s! Welcome to Go programming.", name)
}

// Personalized creates a personalized greeting with language preference.
// This demonstrates error handling, a Go best practice.
func Personalized(name, language string) (string, error) {
    if name == "" {
        return "", fmt.Errorf("name cannot be empty")
    }

    name = strings.TrimSpace(name)
    language = strings.ToLower(strings.TrimSpace(language))

    var greeting string
    switch language {
    case "go", "golang":
        greeting = fmt.Sprintf("Hello, %s! Ready to Go? 🚀", name)
    case "spanish":
        greeting = fmt.Sprintf("¡Hola, %s!", name)
    case "french":
        greeting = fmt.Sprintf("Bonjour, %s!", name)
    default:
        greeting = fmt.Sprintf("Hello, %s!", name)
    }

    return greeting, nil
}

// Constants demonstrate Go naming conventions
const (
    DefaultLanguage = "english"
    MaxNameLength   = 50
)

// Exported variables use PascalCase
var SupportedLanguages = []string{"english", "spanish", "french", "go"}
Enter fullscreen mode Exit fullscreen mode

Running the Application

go run main.go
Enter fullscreen mode Exit fullscreen mode

Building the Application

go build -o hello-world-app
./hello-world-app
Enter fullscreen mode Exit fullscreen mode

Testing

go test ./...
Enter fullscreen mode Exit fullscreen mode

Key Go Best Practices Demonstrated:

  • ✅ Proper module initialization with domain-based naming
  • ✅ Package organization (internal/ for private packages)
  • ✅ Exported vs unexported identifiers (PascalCase vs camelCase)
  • ✅ Function documentation following Go conventions
  • ✅ Error handling with multiple return values
  • ✅ Clear, descriptive naming without underscores
  • ✅ Separation of concerns (main.go stays minimal)

Top comments (0)