В изначальном варианте было несколько проблем.
- Первая была в том, что метод
add()
вызывается параллельно с помощью горутин, что приводит к гонке, так как срезphones
может модифицироваться из нескольких горутин одновременно без синхронизации. - Вторая вытекает из первой: функция
main()
завершает выполнение до того, как все горутины завершат добавление номеров в список. - Ещё я не до конца понял, зачем в функции
randPhone()
мы что-то добавляем, а что-то вычитаем. Я её немного поменял.
Первые две проблемы можно вылечить через добавление Mutex
, но кажется, проще вообще не использовать горутины для такой низкоресурсной задачи.
Соответственно, итоговый результат должен выглядеть как-то так:
package main
import (
"fmt"
"math/rand"
)
type testData struct {
phones []int
}
func (td *testData) add() {
td.phones = append(td.phones, randPhone())
}
func generate(n int, td *testData) {
for i := 0; i < n; i++ {
td.add()
}
}
func main() {
td := testData{}
generate(100, &td)
fmt.Println(len(td.phones))
}
func randPhone() int {
return 89090000000 + rand.Intn(9999999)
}
Я решил проявить инициативу и немного переписать исходный код, чтобы в main() лежало только выполнение функций и выглядело субъективно чуть красивее. И уже на свой код написал тесты.
Тесты писал, пытаясь добиться 100% покрытия и 100% значения мутационного индикатора.