I think they write this to make the example simple, but I wondered in the real case, the Output can be any type, so how do people save these futures if they are writing an executor?
You can define a trait that you implement on any future, and which doesn't have the output be part of the trait. When it completes, the trait would write the result to some other memory location (e.g. send it to the JoinHandle object) rather than returning it from the function.