package concurrency type WebsiteChecker func(string) bool type result struct { string bool } func CheckWebsites(wc WebsiteChecker, urls []string) map[string]bool { results := make(map[string]bool) resultChannel := make(chan result) for _, url := range urls { // anonymous function call required because go routines must call // a function to start. An anonymous function maintains access to // the lexical scope in which they are defined - all the variables // that are available at the point when you declare the anonymous //function are also available in the body of the function. // url := url // create a new variable to avoid capturing the loop variable. // go func() { // results[url] = wc(url) // }() go func(u string) { resultChannel <- result{u, wc(u)} // send statement }(url) // or just pass by value to give the func it's own url } // Improvement idea. We could use a wait group here. Instead we are blocking // each go routine because we are using an unbuffered channel. for i := 0; i < len(urls); i++ { r := <-resultChannel // receive statement results[r.string] = r.bool } return results }