Closures are anonymous functions, which are functions without names that we can save inside a variable
or pass as an argument to other functions.
The best way to learn this is by doing it.
So let's get some code going.
Because I believe the best way to learn closures is to see how they are useful.
So let's create a sample program and then refactor in closures.
So the first thing I want to do is create a new struct called City.
And then here we're going to have the city name, which is a string, and then the population, which
is going to be an unsigned 64.
And then we're going to create a function called sort pop for sort population.
And then in here we are going to take in a vector
of type city and then we'll just call city dot sort.
And we see that we're already getting the red squiggly line error.
And if we hover over it and scroll down to the bottom, it says standard CFP for compare Ord is not
satisfied.
So for us to be able to do this sorting, we need to create a helper function.
So I'll call it pop helper for population helper.
And then in here we'll take our population and it will be a reference to a city and then it's going
to return our unsigned 64.
And then here, we'll just take our pop dot population.
So now we can come back up here.
And instead of saying sort, we'll say sort by key, and then we'll call our pop.
Helper function.
So now if we come down here, let's get some sample data going.
We'll say and we'll just keep our cities very bland and not fun at all.
We'll call and create a new city.
Call it city.
And our string from and our city name is going to be a very creative.
I know.
And then our pop insulation, we'll give it 100.
It's a very small city.
So now we'll do this and we'll just create a few of them and we'll go to.
And then we'll be b c.
The.
An E.
And then we'll just fill in here as well.
C, D and E and let's change up our population some.
We'll go 57.
We'll go 140.
We have a population of five and then our last city will have a population of 70.
And then we'll create a new mutable vector
of type city.
And we will initialize it.
And now we'll just push in all of our cities that we created.
And we have B, C, D and E.
So now let's call our sort population method and we'll pass in our vector.
And then we want to be able to print out.
Our vector sorted,
which we can do.
As such.
It looks like we have a little air.
Oh.
Derive debug.
So we will add that in and now our error is gone.
Awesome.
So now if we run this, we expect our vector to be sorted from.
Population to graze, which we can see population 1557 7101 40.
So we see that it is sorted in ascending order, which is what we wanted.
But now let's see how we could have done this using a closure.
So what we can do is come here and we'll just go ahead and just comment those two out.
And now we'll create a new function called sort pop and then we'll just put closure in here.
That way we can differentiate.
Our functions and we'll have a reference to immutable vector again of type city.
And then in here we will say pop sort by key.
So the same function and now we will create our closure.
So we'll have a.
The two vertical lines.
And then inside we'll have P and in this case, p is going to be our argument into the closure.
And then we'll do pop or excuse me, p dot population.
So we're passing in our P parameter and now we have access to the population which is obviously inside
of our city struct.
And now if we run it again.
Oop.
Sought closure.
Here we go.
And now if we run it, we see that we get the same exact output with the order being in ascending order.
So this is just was a super simple way of showing where closures can help us out.
We were able to go from this was a simple example, but from two functions down to one.
And we were able to contain all of our logic inside of one line.
Obviously, closures can do much more.
So let's look at how we can further use closures and a little bit more of the details into how closures
work.