When we want to create the function of multiple forms, i.e., the parameters of the function can accept the multiple types of data. This can be achieved through generics. Generics are also known as 'parametric polymorphism' where poly is multiple, and morph is form.
There are two ways to provide the generic code:
1. Option<T>: Rust standard library provides Option
In the above case, enum is the custom type where <T> is the generic data type. We can substitute the 'T' with any data type. Let's look at this:
In the above case, we observe that 'T' can be of any type, i.e., i32, bool, f64 or char. But, if the type on the left-hand side and the value on the right hand side didn't match, then the error occurs. Let's look at this:
In the above case, type on the left-hand side is i32, and the value on the right-hand side is of type f64. Therefore, the error occurs "type mismatched".
2. Result<T,E>: Rust standard library provides another data type Result<T,E> which is generic over two type, i.e., T &E:
Note: It is not a convention that we have to use 'T' and 'E'. We can use any capital letter.
Generics can be used in the functions, and we place the generics in the signature of the function, where the data type of the parameters and the return value is specified.
The above syntax has two parts:
When the function contains multiple arguments of the same type.
When the function contains arguments of multiple types.
Structs can also use the generic type parameter in one or more fields using <> operator.
In the above syntax, we declare the generic type parameter within the angular brackets just after the structure_name, and then we can use the generic type inside the struct definition.
Let's see a simple example:
integer values : 2,3 Float values : 7.8,12.3
In the above example, Value<T> struct is generic over one type and a and b are of the same type. We create two instances integer and float. Integer contains the values of type i32 and float contains the values of type f64.
Let's see another simple example.
In the above example, Value<T> struct is generic over one type, and a and b are of the same type. We create an instance of 'c'. The 'c' contains the value of different types, i.e., i32 and f64. Therefore, the Rust compiler throws the "mismatched error".
An enum can also use the generic data types.Rust standard library provides the Option<T> enum which holds the generic data type. The Option<T> is an enum where 'T' is a generic data type.
It consists of two variants, i.e., Some(T) and None.
Where Some(T) holds the value of type T and None does not contain any value.
In the above case, Option
In the above case, Result<T, E> is an enum which is generic over two types, and it consists of two variants, i.e., OK(T) and Err(E).
OK(T) holds the value of type 'T' while Err(E) holds the value of type 'E'.
We can implement the methods on structs and enums.
Let's see a simple example:
p.a() is 5
In the above example, we have implemented the method named as 'a' on the Program<T> that returns a reference to the data present in the variable a.
We have declared the 'T' after impl to specify that we are implementing the method on Program<T>.
Rust compiler automatically infers the generic parameters. Let's understand this through a simple scenario:
In the above case, we insert the integer value into the vector. Therefore, the Rust compiler got to know that the vector v has the type i32.
If we delete the second last line, then it looks like;
The above case will throw an error that "it cannot infer the type for T".
1. We can use the following annotation:
2. We can bind the generic parameter 'T' by using the 'turbofish' ::<> operator: