Understanding Generics in Rust lang

Alfred is a software engineer and cyber security specialist based in Enugu, Nigeria. He is passionate about solving real-world problems through well-crafted software and leveraging blockchain technology.
Search for a command to run...

Alfred is a software engineer and cyber security specialist based in Enugu, Nigeria. He is passionate about solving real-world problems through well-crafted software and leveraging blockchain technology.
No comments yet. Be the first to comment.
The tech industry is changing fast—but not in the way most people think. By 2026, success in engineering won’t be about chasing the newest tools or stacking buzzwords on a résumé. It will be about depth, ownership, and usefulness. Here’s a grounded l...

1. Server Streaming RPC: Description: In this type of RPC, the client sends a single request to the server, and the server responds with a stream of messages. The client reads from this stream of responses until there are no more messages. Use Case...
Email communication is a crucial aspect of many applications, and Amazon Simple Email Service (SES) provides a reliable and scalable solution for sending emails in the Amazon Web Services (AWS) environment. I've created a go package that facilitates ...

Introduction This article shows a complete setup on how you can verify a signature sent by paystack when they make a POST request to your server. I'm using the bun http router as my go lang framework. I really do not have strength for long talks, so ...
Funny title, but that's the reality from January to December. So, you're here to hear some gist about my 2023, say less. First I just want to take a moment to laugh small, 😂😂😂😂 why? the plans I had for 2023 come be like say na small pikin write a...

Generics is a fundamental part of the rust programming language and can sometimes be a pain to truly understand its use and purpose. In this article, I'll try and explain this concept like you are a kid ( if you are not ).
Generics can be associated with functions, enums, structs, return type and variables.
pub fn returnData (name: &char) -> &char{
name
}
pub fn returnData<T> (name: T) -> T{
name
}
The first function can be identified as a regular function with no generic syntax, but on the other hand, we have another function, which does the same thing but this time uses a generic.
We can consider the second function as a better approach, why? Utilizing generics, in this case, gives us the freedom to pass any data type as a parameter, unlike the first function which requires only a parameter of data type &char.
returnData<T> means, this function accepts one parameter of type T. T literally means, any type e.g int, uint, floats, struct, etc. You could actually name is anything but the convention is T which means Type, we can decide to re-write the function using a new name like returnData<MyType>, and this works fine so far as you use this same name as the parameter type (name: MyType) and maybe a return type ( -> MyType). The whole <T> thing you see is the presence and usage of a generic.
fn main() {
pub fn returnData<T> (name: T) -> T{
name
}
let data = returnData(String::from("Alfred"));
let age = returnData(27);
println!("{} is my name", data);
println!("{} is my age", age);
}
Try it here.
struct User {
name: &String,
email: &String,
age: u8
}
struct User<T,U> {
name: T,
email: T,
age: U
}
Structs are used to create user-defined data structures, and we can use generics to make them even better. You can see the difference between the two structs, the second introduced the generic data type.
Focusing on the second struct, with name as User, we expect this struct to have fields with either a data type of T or/and U. Again, T could be of any type i.e signed integer, unsigned integer, floating-point numbers, or even char.
fn main(){
struct User<T,U,V> {
name: T,
email: U,
age: V
}
struct Fullname {
fname: String,
lname: String
}
let user1: User<&str, &str, f64> = User { name: "Alfred",
email: "alfred@codemon.me", age:10.1};
let _fullname = Fullname { fname: String::from("alfred"),
lname: String::from("johnson") };
let user2: User<Fullname, &str, u8> = User { name: _fullname,
email: "fred@gmail.com", age: 32};
println!("User 1: name is {}, email is {} and age is {}",
user1.name, user1.email, user1.age);
println!("User 2: first name is {}, last name is {}, email is {} and age is {}",
user2.name.fname, user2.name.lname, user2.email, user2.age)
}
Try it here.
Enums are similar to structs mostly in syntax but personally, it's used to define custom data types just like structs. The fields in an enum are expected to be related in some way, unlike struct which gives more flexibility.
enum Colors {
red,
green,
blue,
custom(String)
}
enum Colors <T>{
red,
green,
blue,
custom(T)
}
Web developers know we can represent colors in different ways, hex, RGB, or by their name. The first enum does not give room for us to create a custom color, it must be a string. But with the second enum, we can define a custom color in our enum. Assuming we want to represent a custom RGB color, we can proffer a solution as seen below.
fn main(){
enum Colors <T>{
Green,
Blue,
Custom(T)
}
let white_tuple = ("#","f","f","f");
let white: Colors<(&str, &str, &str, &str)> = Colors::Custom(white_tuple);
let blue: Colors<(&str, &str, &str, &str)> = Colors::Blue;
let green: Colors<(&str, &str, &str, &str)> = Colors::Green;
}
I hope you've been able to understand the generic syntax and maybe give you a solution to a problem you have been trying to solve.