package main import ( "fmt" "strings" "time" ) // generator produces initial string data func generator(input []string) <-chan string { out := make(chan string) go func() { defer close(out) for _, s := range input { fmt.Printf("Generator: Sending '%s' ", s) out <- s time.Sleep(100 * time.Millisecond) // Simulate some work } }() return out } // upperCaseStage converts strings to uppercase func upperCaseStage(in <-chan string) <-chan string { out := make(chan string) go func() { defer close(out) for s := range in { upper := strings.ToUpper(s) fmt.Printf("UpperCaseStage: Processed '%s' -> '%s' ", s, upper) out <- upper time.Sleep(150 * time.Millisecond) // Simulate some work } }() return out } // reverseStage reverses the processed strings func reverseStage(in <-chan string) <-chan string { out := make(chan string) go func() { defer close(out) for s := range in { runes := []rune(s) for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 { runes[i], runes[j] = runes[j], runes[i] } reversed := string(runes) fmt.Printf("ReverseStage: Processed '%s' -> '%s' ", s, reversed) out <- reversed time.Sleep(120 * time.Millisecond) // Simulate some work } }() return out } func main() { data := []string{"hello", "world", "golang", "channels"} // Chain the pipeline stages stage1 := generator(data) stage2 := upperCaseStage(stage1) finalStage := reverseStage(stage2) fmt.Println("Main: Starting pipeline. Final results:") // Consume the final results for result := range finalStage { fmt.Printf("Main: Final result: %s ", result) } fmt.Println("Main: Pipeline finished.") }