- It's quite common to return a structure from a function.
It lets you return a lot of data as a cohesive bundle
in a single object and that can be useful
to the calling function.
You return a lot of data back to the caller in one object,
they can then use that data as they like.
So there were two ways to return a structure
from a function.
You can either return by value,
which we'll have a look at now,
or you can return by reference,
which we'll have a look at a bit later.
So have a look at this function.
It's called build_employee.
I've given it name build_employee,
and it takes some parameters as input.
It takes in the person's name as a parameter,
and the salary and a full-time status of boolean.
And it returns an employee,
it returns an employee object by value.
And that's what this does.
Remember when you have a function,
if you have an expression at the end of the function,
then it's like having a return statement.
This is returning an employee
whose name field is set to the name parameter
and whose salary field is set to the salary parameter
and whose full-time status is set to full-time status.
Okay, so you pass three parameters into this function.
What you'll get back is a properly initialized employee.
These are the names of the fields
and these are the parameters
that we're going to use to initialize them.
So this is a builder function.
It encapsulates creating a structure instance.
It returns the structure back to the caller.
Here's the employee that's just been built.
Okay, so it's quite common
to like build a functions like this.
As an aside, the syntax that we've got here
where we kind of manually initialize the name field
to be the value of the name parameter and the salary field
to be the salary and the full-time field
to be the full-time status like that,
this syntax can be simplified to this syntax,
if the field name is the same as the value name,
if you like, if the field is called salary,
and the parameter is called salary,
then instead of saying name equals name,
salary equals salary, full-time equals full-time,
you can just use this syntax, this abbreviated syntax is
what you'd actually use in practice.
It only works if the name of the field is the same
as the parameter.
Okay, it'll use the name parameter to initialize the name,
the salary parameter to initialize the salary
and the full-time parameter
to initialize the full-time field.
Okay, so obviously that makes sense,
just make sure that when you name these parameters,
they have the same name as the fields
and they will automatically be transferred
into each field respectively, so that syntax,
you would agree, is a lot simpler than that syntax.
So let's go for this.
It means that when we call the function,
we'll get back an employee.
So let's have a look at how that works.
We can mark the employee as mutable if we want to or not.
If we don't,
so I've called the builder function build_employee.
I've passed in three parameters,
a string for the person's name, their salary,
and their full-time status.
This will gimme back an employee object,
which in this first case is not mutable.
In the second case I call the build_employee function again,
I pass in different parameters.
I get back another employee object
which I assign to e2 and e2 is mutable,
which means I can change anything in the employee object.
So having these builder functions is convenient
because it kind of encapsulates the creation of the object
and the passing in of fields into the object.
It makes it a neater syntax.
Right, so let's have a look.
Usual project.
The files we're going to look at,
obviously mytypes.rs defines the employee structure.
main.rs coordinates the whole program
and the demo file for this part of the example,
demo_struck_return_value and then we'll run it at the end.
So let's have a look.
Okay, so mytypes.rs, that's the employee structure.
We've seen that many times now.
My main code,
I'm going to un-comment demo_struck_return_value,
and let's have a look at it here.
All right, so what have we got going on here then.
I've got a builder function, which when you call it
with a person's name and salary and full-time status,
it returns an employee object.
Let's have a look.
Okay, so this one is using the kind of verbose syntax
where it takes the parameter name and stores it in name,
it takes the salary parameter and transfers it
to the salary field, and the full-time flag
and passes it in here, so in this case here,
I could have called these parameters n,
or anything really, an s, an f.
Okay and then here I'd have said
the name field is initialized with n,
the salary field is initialized with s,
and the full-time field is initialized with f.
Okay, it's effectively doing that,
but obviously it makes a lot more sense
to give the parameters the same names as the fields.
I've called this build_employee_v2,
and it's much better.
So there it basically creates an employee object
and implicitly initializes the name with the name parameter,
the salary with a salary parameter,
and the full-time with a full-time parameter.
And this only works because the fields have the same name
as the parameters.
If this parameter was called n and s and f,
then this wouldn't work.
It would say, I'm looking
for like an external variable called name, where is it?
You'd have to use name, colon, n,
and then we're back to square one.
So let's not do that.
Let's name the prompters the same as the field names,
and then they will automatically be transferred here.
And like I was saying, when you have a function
with an expression at the end,
then it's implicitly the return value, so if I wanted to,
I could have said return employee semicolon,
but if it's the last expression,
then it's implicitly the the return value.
So that's the way Crusty the Crustacean would write it.
Oh and then finally, I've got a function
that takes an employee by reference,
and it prints the data for the employee,
the name and the salary and the full-time status.
Okay, so let's just run the code up here.
So I create an employee using the first version
of the builder, and e1 isn't mutable.
I print the employee details
and then I create employee two using the second version
of my builder function,
the improved version with the more concise syntax down here.
And that employee object would be John.
And I've decided to make that employee mutable,
which means I can employee salary rise,
and then finally I print employee two as well.
So I feel like we should just run this just to make sure.
Okay, so I built employee one, Jane, 1000, true.
And then I print employee one, Jane, 1000, true.
And then I create a mutable employee,
John, 1000, false, give them a thousand pay rise
and then print John's details and John's details are here.
So this is a really widely used mechanism.
We'll take it a step further in the next lesson
and I'll show you what that means later.
But having a function whose responsibility is
to create and return an object
with the initial values is a very useful thing
because it means your code
up here is just a simple function call.
And you know, rather than having
to create the employee explicitly,
you get the employee back already initialized
through the field so it's quite elegant
and that's the way to do it.