Функция main
считывает json из файла, разворачивает ее в структуру, преобразует ее в другой тип структуры и выплескивает форматированный JSON через stdout.goroutine channels over a for loop
Я пытаюсь реализовать goroutines и каналы, чтобы добавить параллелизм в мой цикл for
.
func main() {
muvMap := map[string]string{"male": "M", "female": "F"}
fileA, err := os.Open("serviceAfileultimate.json")
if err != nil {
panic(err)
}
defer fileA.Close()
data := make([]byte, 10000)
count, err := fileA.Read(data)
if err != nil {
panic(err)
}
dataBytes := data[:count]
var servicesA ServiceA
json.Unmarshal(dataBytes, &servicesA)
var servicesB = make([]ServiceB, servicesA.Count)
goChannels := make(chan ServiceB, servicesA.Count)
for i := 0; i < servicesA.Count; i++ {
go func() {
reflect.ValueOf(&servicesB[i]).Elem().FieldByName("Address").SetString(Merge(&servicesA.Users[i].Location))
reflect.ValueOf(&servicesB[i]).Elem().FieldByName("Date_Of_Birth").SetString(dateCopyTransform(servicesA.Users[i].Dob))
reflect.ValueOf(&servicesB[i]).Elem().FieldByName("Email").SetString(servicesA.Users[i].Email)
reflect.ValueOf(&servicesB[i]).Elem().FieldByName("Fullname").SetString(Merge(&servicesA.Users[i].Name))
reflect.ValueOf(&servicesB[i]).Elem().FieldByName("Gender").SetString(muvMap[servicesA.Users[i].Gender])
reflect.ValueOf(&servicesB[i]).Elem().FieldByName("Phone").SetString(servicesA.Users[i].Cell)
reflect.ValueOf(&servicesB[i]).Elem().FieldByName("Username").SetString(servicesA.Users[i].Username)
goChannels <- servicesB[i]
}()
}
for index := range goChannels {
json.NewEncoder(os.Stdout).Encode(index)
}
}
Она компилирует, но возвращает сообщения, как:
goroutine 1 [chan receive]: main.main() C://.....go.94 +0x55b.
Благодарим вас за ответ, Эван. Я решил использовать буферный канал, потому что мне нужно преобразовать и распечатать несколько структур. Как мне это сделать без буферизованного канала? –
@ScottS. вы можете просто использовать массив для этих целей. Идея канала состоит в том, чтобы обеспечить связь между вашими рабочими потоками и вашим прикладным уровнем, вы можете использовать буферный, это редко делается и немного меняет свою механику. Обычно канал блокируется до тех пор, пока он не читается, поэтому вы должны использовать цикл for, подобный тому, который был у меня выше, который просто продолжает читать канал, пока горутин не говорит, что это сделано, или вы получаете сигнал отключения или прерывания из другого источника. – evanmcdonnal
Если вы собираетесь использовать буферный канал, чтобы просто вставить в него весь массив, вы можете вообще не использовать goroutine, просто используйте блокирующий вызов, потому что вы не будете передавать ваши данные в этот момент, просто подготовьте его асинхронно, ничего не делая, кроме как ждать, пока это будет сделано. – evanmcdonnal