Go Programming Language Tutorial (Part 3)
Go Programming Language Tutorial (Part 3)
This tutorial focuses on interfaces, testing techniques, error handling best practices, concurrency
patterns, and package development.
1. Interfaces
What is an Interface?
An interface in Go defines a set of method signatures. A type implements an interface if it defines those
methods.
import "fmt"
// Define an interface
type Shape interface {
Area() float64
Perimeter() float64
}
// Circle type
type Circle struct {
Radius float64
}
// Rectangle type
type Rectangle struct {
Length, Width float64
}
func main() {
// Polymorphism with interface
shapes := []Shape{
Circle{Radius: 5},
Rectangle{Length: 10, Width: 4},
}
import (
"fmt"
)
func main() {
result, err := divide(10, 0)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Result:", result)
}
}
3. Advanced Testing
Table-Driven Tests
Table-driven testing is an efficient way to test multiple cases.
go
Copy code
package main
import "testing"
// Function to test
func Add(a, b int) int {
return a + b
}
import (
"fmt"
"testing"
)
// Service interface
type Service interface {
GetData() string
}
// Real implementation
type RealService struct{}
func (r RealService) GetData() string {
return "Real Data"
}
4. Concurrency Patterns
Worker Pools
Worker pools distribute tasks among multiple Goroutines.
go
Copy code
package main
import (
"fmt"
"sync"
)
// Worker function
func worker(id int, jobs <-chan int, results chan<- int, wg *sync.WaitGroup) {
defer wg.Done()
for job := range jobs {
fmt.Printf("Worker %d processing job %d\n", id, job)
results <- job * 2
}
}
func main() {
jobs := make(chan int, 5)
results := make(chan int, 5)
var wg sync.WaitGroup
// Start workers
for i := 1; i <= 3; i++ {
wg.Add(1)
go worker(i, jobs, results, &wg)
}
// Send jobs
for j := 1; j <= 5; j++ {
jobs <- j
}
close(jobs)
// Collect results
for result := range results {
fmt.Println("Result:", result)
}
}
Select Statement
Use select to wait on multiple channels.
go
Copy code
package main
import (
"fmt"
"time"
)
func main() {
ch1 := make(chan string)
ch2 := make(chan string)
go func() {
time.Sleep(2 * time.Second)
ch1 <- "Channel 1"
}()
go func() {
time.Sleep(1 * time.Second)
ch2 <- "Channel 2"
}()
import (
"fmt"
"mypackage/math"
)
func main() {
fmt.Println("Sum:", math.Add(2, 3))
}
import (
"encoding/json"
"net/http"
)
func main() {
http.HandleFunc("/user", getUser)
http.ListenAndServe(":8080", nil)
}
7. Managing Dependencies
Using go mod
1. Initialize a module:
bash
Copy code
go mod init example.com/myproject
2. Add dependencies:
bash
Copy code
go get github.com/gin-gonic/gin
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{"message": "pong"})
})
r.Run(":8080")
}
This tutorial explores key intermediate and advanced Go features. It prepares you for real-world Go
development, including creating reusable packages, managing dependencies, and building scalable
applications. Dive deeper into advanced concurrency, reflection, and Go's standard library for further
learning!