Почему это работает?

Есть вот такой код, для подсчета кол-ва символов в тексте, передающимся абзацами.
package main

import (
	"fmt"
)

type FreqMap map[rune]int

func Frequency(s string) FreqMap {
	m := FreqMap{}
	for _, r := range s {
		m[r]++
	}
	return m
}

func ConcurrentFrequency(list []string) FreqMap {
	resChan := make(chan FreqMap, len(list))

	for _, letter := range list {
		letter := letter
		go func() {
			resChan <- Frequency(letter)
		}()
	}

	res := make(FreqMap)
	for range list {
		for letter, freq := range <-resChan {
			res[letter] += freq
		}
	}

	return res
}

func main() {
	text := []string{"hello, my dear friend", "hello, my dear enemy", "hello, my dear frenemy"}

	f := ConcurrentFrequency(text)
	fmt.Println(f)
}

Объясните, пожалуйста, почему это отрабатывает правильно. Почему возник такой вопрос - потому, что вот этот код, который, вроде бы, идентичный, отрабатывает не так как тот и лочится. Не могу понять, что я упустил?
package main

import (
	"fmt"
	"strings"
)

func Words(text, word string) int {
	counter := 0

	for _, w := range strings.Split(text, " ") {
		if w == word {
			counter++
		}
	}

	return counter
}

func ConcurrentWords(list []string, word string) int {
	resChan := make(chan int, len(list))
	counter := 0

	for _, text := range list {
		text := text
		go func() {
			resChan <- Words(text, word)
		}()
	}

	for count := range resChan {
		counter += count
	}

	return counter
}

func main() {
	text := []string{"hello, my dear friend", "hello, my dear enemy", "hello, my dear frenemy"}

	w := ConcurrentWords(text, "hello")
	fmt.Println(w)
}
  • Вопрос задан
  • 116 просмотров
Пригласить эксперта
Ответы на вопрос 1
uvelichitel
@uvelichitel
habrahabr.ru/users/uvelichitel
Во втором случае блокирует цикл
for count := range resChan {
из такого цикла можно выйти только когда канал будет где нибудь явно закрыт close(resChan), но у вас нет надежного места где закрыть. Поэтому переписать например так
for count := 0; count < len(list); count++ {
	counter += <-resChan
}

Кроме того вы считаете входения "hello", а у вас только входения "hello," вы ведь разбиваете пробелами а не запятыми. Вот работающий код https://play.golang.org/p/DbsqnN1kxOY
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы