Go makes concurrent work straightforward with goroutines. One practical example is searching for a word across many text values at the same time.

Instead of checking each text sequentially, you can launch a goroutine for each item and wait for all searches to finish.

Overview

The program below will:

  1. Search for a word in a single text value with searchInText.
  2. Search multiple text values concurrently with searchWordInTexts.
  3. Print whether the word was found.

Complete Example

package main

import (
	"fmt"
	"strings"
	"sync"
)

// searchInText reports whether word occurs in text.
func searchInText(text, word string) bool {
	if text == "" || word == "" {
		return false
	}

	// Make the search case-insensitive.
	text = strings.ToLower(text)
	word = strings.ToLower(word)
	return strings.Contains(text, word)
}

// searchWordInTexts searches multiple texts concurrently.
func searchWordInTexts(texts []string, word string) bool {
	var wg sync.WaitGroup
	var mu sync.Mutex
	found := false

	for _, text := range texts {
		wg.Add(1)
		go func(t string) {
			defer wg.Done()
			if searchInText(t, word) {
				mu.Lock()
				found = true
				mu.Unlock()
			}
		}(text)
	}

	wg.Wait()
	return found
}

func main() {
	texts := []string{
		"This is a long example text",
		"Another text for word searching",
		"This program uses goroutines for searching",
	}
	word := "program"

	if searchWordInTexts(texts, word) {
		fmt.Printf("Word '%s' was found in at least one text\n", word)
	} else {
		fmt.Printf("Word '%s' was not found\n", word)
	}
}

How It Works

  1. searchInText converts both the text and search term to lowercase, then uses strings.Contains for a case-insensitive match.
  2. searchWordInTexts uses sync.WaitGroup to wait for every goroutine and sync.Mutex to protect the shared found variable.
  3. main provides sample data, runs the concurrent search, and prints the result.

A Practical Note

For short in-memory strings, launching one goroutine per string may be slower than a simple loop because goroutines and synchronization have overhead. This pattern becomes more useful when each task is expensive or blocking, such as reading files, calling services, or processing large independent inputs.

Conclusion

With goroutines plus WaitGroup and Mutex, Go can coordinate concurrent searches with only a small amount of code. The same pattern can be adapted to other independent workloads that benefit from running concurrently.