[No Audio]
This tutorial is about a special concept in
Rust called trait bounds. We covered the
trait in Section 5 of the course in the
context of structures, let us recall that.
A trait defines a particular functionality data
type has, which it can share with other types.
We can use traits to define shared behavior
in an abstract way. For instance, we can have
a trait of general info for the Student and
Person types, giving us some general
information about the respective types. The
trait bounds are used to specify and restrict
the generic types to only those types, which
has certain behavior, or more specifically has
certain traits, that are implemented for that
specific type. Let's look at an example which
will make things more obvious and easy to
comprehend. Consider a simple program which
uses a double function to compute a quadruple
of a given number, by calling the double
function twice, Let us implement the double
function inside a trait called Double.
[No Audio]
The trait called Double containing a single
function of double, which returns the double
of the given type, let us implement this
trait for an i32.
[No Audio]
This was simple. Let us now include the
quadruple function now, which will call the
double function twice.
[No Audio]
Let us call the quadruple function from the
main now inside the print statement.
[No Audio]
This however, will only work for an i32
type. What if I want the same for an i64 type?
I will implement the same Double for an
i64 type also, so let me do it.
[No Audio]
So, now we have the Double for i64, but the
function quadruple is only for i32, this
means that, I will need to define another
function for i64 also, it will be
pretty pedestrian to approach it like this.
Luckily, we have generics in Rust, which we
can introduce instead, which will relax the
condition on the inputs to be of some
specific type only. Let us
introduce the generic of T in this case.
[No Audio]
Let us execute this now.
[No Audio]
It appears that the compiler does not like
this at all. It says, items for trait can only
be used if the type parameter is bounded by
the trait. Let us look at it in some detail.
First, the compiler notice that the quadruple
works on any type T, that's fine. This means
that, whoever calls this function gets to
decide what T is, that is also fine. However,
the compiler has no way of knowing if t is
going to have a method called Double on it.
If it happens to be an i32 or i64, then it
will have it, but if it is i16 or i8, then
it will not have it. Since there is no
restriction on the type of T, therefore the
compiler has no way of assuring that T will
always be going to have a method called
double on it. The compiler is however smart
enough to notice that there is a trait called
double, which provides a double method. Maybe
that's what we want it to use. It therefore
gives a nice suggestions that you need to
introduce a trait bound. Let me add a trait
bound to the parameter T.
[No Audio]
The trait bounds introduces a
restriction on the types that a
caller can use when using type parameters.
Uptil now, we have seen unbounded type parameters,
which means, you can use whatever, whatever
type you want. However, with quadruple it is
using an item from a trait of Double. Uptil
now, we have seen unbounded type parameters,
which means, you can use whatever type you
want. However with quadruple, it is using an
item from a trait of double. By item we mean, a
function in this case, which is only defined
for some specific type, and therefore we
cannot be so accepting in this case. Instead,
we would we want to say, okay, you can give me
lots of different types for the, for the
generic T, but just make sure they implement
the Double trait. In some sense, we are
telling the compiler that, T can be any type
which has the behavior or property of Double
implemented for it. If it does not implement
Double, then the compiler, then the compiler
will run into issues of exactly determining
the type for the parameter T. The programmer
now has the responsibility of when calling
the quadruple function, to make sure that the
type we are using has an implementation for
Double. That is it for this tutorial. I hope
you would have enjoyed this. Do come back
again for more, and until then enjoy Rust programming.
[No Audio]