- Learning Functional Programming in Go
- Lex Sheehan
- 321字
- 2021-07-02 23:13:43
The GenerateCars function
Here's the actual generator function:
func (cars Collection) GenerateCars(start, limit int) Collection {
carChannel := make(chan *IndexedCar)
The GenerateCars is another method in the cars collection that makes it easy to compose data transformations with other HOFs. GenerateCars takes a start index and limit, which is the number of cars that we want to be returned. We create carChannel of pointers to IndexedCars:
var waitGroup sync.WaitGroup
We use sync.WaitGroup as a counting semaphore to wait for our collection of Goroutines to finish:
numCarsToGenerate := start + limit - 1
generatedCars := Collection{}
waitGroup.Add(numCarsToGenerate)
We calculate the number of cars we want to generate and pass that number to the waitGroup.Add function:
next := carGenerator(iterator, start -1, numCarsToGenerate)
Our carGenerator function returns a function that we assign to a variable named next:
carIndex, done := next()
The next variable returns two variables: carIndex and done. As long as there are more cars to generate, done will be false. So, we can use done to control a for loop that launches a Goroutine, one for each car to generate:
for !done {
go func(carIndex int) {
thisCar, err := GetThisCar(carIndex)
if err != nil {
panic(err)
}
carChannel <- thisCar
generatedCars = append(generatedCars, thisCar.Car)
waitGroup.Done()
}(carIndex)
carIndex, done = next()
}
The next variable returns two variables GetThisCar(carIndex) in the code block; immediately after this, the preceding code calls the RESTful car service that returns the requested car.
If an error is encountered, we use the built-in function panic to stop the execution of the current Goroutine. Since we used a deferred function, namely csvfile.Close(), in the call stack, it will be executed if a panic occurs. Note that we could have had more control over the termination sequence using the built-in recover function.
The thisCar variable is sent to carChannel, and the Car field is appended to the generatedCars collection.