Intro to Rustlang (Traits and Generic Types)

Tensor Programming · Beginner ·📐 ML Fundamentals ·8y ago

Key Takeaways

The video covers Traits and Generic Types in Rustlang, demonstrating how to define shared behavior across data types and generalize types using generics.

Full Transcript

hey guys welcome back to introduction to rust my name is tensor this will be video eight in our series today we'll be talking about traits in generics so we've kind of already touched on traits through the define annotation as well as implementing deeper but traits are essentially a way for us to define shared behavior over multiple different I guess sets of data traits are very similar to interfaces in other languages they allow us to define what a function should look like and then allow us to implement that function into various different data types so to create a trait you just use the trait keyword and we're gonna create one called shape and this trait will have a single function inside of it you see here that it takes a reference of self and returns a u-32 and so we have here two strikes one's a rectangle and the other one's a circle so this one has an x and y and this one has a radius and so now we've implemented shape for a rectangle and you see here we just created an area function that multiplies x times y and then we can implement it for circle like this and of course because we have to pass back to you 32 we can cast the result of multiplying the radius by itself and then by pi as you 32 we can simply instantiate our Struck's here and then print out the areas like this so you can see here that we got our result of course this was converted to u 32 so it stripped off the decimal points and then this other one is just the multiplication of the two sides so we also have the derive annotation that we can use to implement various different trades compiler is essentially capable of providing basic implementations for specific traits so here we have two strikes a and B 1 has an i-32 in it the other one has an f32 in it we've seen before that you can write a derived annotation above you can put the debug flag in and this will allow us to print out an instantiation of a with a debug flag so that we can see it in the console you also have the copy and clone trait grown is interesting because it gives us a little bit more control over how our variables work inside of our ownership system so you'll see here that if I a an instantiated here and then I assign it to a variable C we can't print it out after it gets assigned to C because it's been moved to C so when we reference a now it doesn't actually reference to this piece of data anymore however because we've annotated it with clone we can actually use a method called clone to clone the variable and now you'll see here that a still references this particular piece of data and C exists as well because it now references a clone of this data now if we want to make it so that we don't have to reference clones specifically every single time we can use the copy treat here and this essentially says that every single time a function or a variable borrows our data it will automatically be copied so this a struct gets instantiated as a and then we move a to C in this case it copies it to C and then we can print it out as we normally would so we don't get an error here that says that it's been moved so we also have multiple different comparison traits as well and we're just going to take a look at them real quick we have the EQ trait and you can see here trade for equality comparisons which are equivalent relations this means that for example a equals B and B does not equal they and so on and so forth and then we have partial EQ which is again more comparison it adds more information to our data type here and we can keep going we also have partial award and partial or it is it gives us a symmetry transitivity and various other things we also have Ord which gives us a symmetry and transitive operations as well so there are many uses for these comparison operators I'm not going to go too much into depth on them right now so we can also use traits to overload operators so we can use our binary operators on these units trucks so for example if we wanted to implement addition for a and B here so that they give us a b and b and a and respectively we could do that so let's take a look at that for instance in this case we're implementing ad for a but we're saying okay we want to implement addition with respect to type B for a and then we have to specify the actual output so the output is going to be of type a B and then we implement our add function here which takes himself and then our HS and we put this all under score because we're not going to use our HS inside the function body and then we say okay this will output an a B type so our a B struct here and then we also need to implement it if we want the addition to work the other way around we need to implement it from the other side as well so we're going to implement addition for B with respect to a we put the output here as B a and then we implement the add function like we did up here now you can see here that I can add the two together so rather than just instantiating each of them I can just say a plus B and B plus a now we'll get some errors if I try to add like a an A or B and B because I didn't implement addition for a for a and for B for B so it doesn't really the compiler doesn't really know what to do with two B's like this or it just kind of throws an error now if we print this out you can just see that we just get a B and then B a back so yeah this can be pretty used for when you want to overload the basic operators inside of rust you also have another trait called drop so here we go I'm implementing drop for our struct a and this is just a basic struct with one single field that's just a string and what drop allows us to do is to specify when we want the compiler to actually drop the value from memory now the interesting thing about drop is that it automatically gets called when the variable gets dropped so even if we don't explicitly use it it will automatically get called so for instance with our a here we have a string that just has a in it B we have a string with B in it and then C we have a string with C in it and we have three different scopes here so our innermost scope C will get dropped when it hits this parenthesis then B will get dropped hisses parentheses and then a will get dropped when the program actually quits and we can actually specify by a calling drop on a here and we want to drop a before the program ends so we'll drop a here and then we'll have the program end and you can see here first it says leaving Interscope two and then we get dropped C and then leaving Interscope one then we get dropped B and then it says program ending and then we get dropped a so basically this runs first then C gets dropped here then this runs next then B gets dropped here and then a gets dropped here even though this gets run first and that's just simply because there's not much more to this program here so we also have an iterator trait which is used to implement iterators there were collections like arrays and stuff in this case we're creating a struct called fib and we're creating an iterator for this specific struct to basically print out a Fibonacci sequence you can see here we've got two fields in this and we implement iterator for fib and then we have to specify the type of collection in this case you 32 and then we have to implement the next function here which takes in a mutable reference to self and outputs an option of you 32 in this case and then we implement basically this here which will essentially create any Fibonacci sequence so we also get various methods that we can use on our iterators so here we have a take method this says okay we want to take the first 10 elements of our iterator and then we want to do this with them so in this case we're just printing them out we're iterating through them each one so then we have our Skip method here which skips the first 14 of this collection and then we take 10 afterwards so basically we skipped the first 14 values then we take the first 10 and then we iterate through them and print them in here we also have the next method which allows us to iterate through our iterator one item at a time our first iteration through we take the first 10 number so 1 2 3 4 5 6 7 8 nine ten so this is the first loop then the second loop skips 14 numbers and then takes ten so from from 987 all the way up to 75,000 here and then this is our us calling the next method on it you see here that it returns the option so it doesn't unwrap it we could use pattern matching to unwrap these to actually get the values out of them or we could just use the unwrap method but that's something that we'll talk about a bit later all right so now let's talk about generics all right so here's an example of a struct that uses a generic so you see here that we have these angle brackets and then we have this capital T inside of this and then for the field here for the type declaration we're using this T again well essentially what this is doing is it is allowing us to generalize the type declaration for this specific struct so now if I instantiate this struct here you can see here that I've instantiate it at four times and this one I've used an integer and this one I've used to float and I've used a slice and here I've used the character and all of these are working perfectly fine generics are extremely useful for a reducing code duplication and you can kind of see that here rather than having to write four different strikes with four different type declarations we just write one here all right so we can also use generics inside of functions so you can see here that we've created a generic here t again we also have this other stuff which we'll get to here in a moment but so we've got this basic function that should be able to print out any type as long as it has the debug trait attached to it so this here is shorthand for deriving the FMT debug trait for our generic T so if you think about this like if we pass in a non primitive type that we can't debug it will throw an error if we just like remove this part of it you'll see here that this actually will come back and say that T does not have the debug trait but if we put this little flag in here then we're basically saying okay well we can run this function on any value that does have the debug trace and you can see that here by us running it on 10 and then running it on a string here so we can use generics and set of implementation rocks here and notice that we've written the generic twice here now the reason we do that is because this struct here is bound to this specific generic so we're saying here that a of t is the the implementation that we want to specifically go on and then here we're specifying another t so you have to remember that this T here is not the same as this T because this T is only scoped to this brach here and the same goes for the T here so for instance if I remove this T here we'll get an error saying that this is not in the scope so we need to specify that we want to have a type here so you can use any other capital letter or capital whatever so like I can make a generic type that looks like this and the compiler won't have an error so even though this one says T here and this one says a KS whatever it still should work you can see here that we can instantiate any and then we can just call a dot item and this will just return a reference to the field inside of a now we can also use generics to sort of define patterns for structs so think about it like this if you look at this struct we have two different generic values and both fields are bound to do different generic values as well so U and V are independent of one another in this case so we could have like a float here and then a character here or we could have two floats inside of here and it would still work whereas with struct B we need to have to the same type for both of the fields so we can't have like a character for X and then like a string for Y it just wouldn't work so in a way this is sort of like a abstract version of pattern matching all right so here's our shape trait that we implemented earlier except this time it's using a generic T and we've created an area here which takes in the reference to self and outputs a t then we're creating a destructor called rectangle which has an X and a Y which are both value T this implements the mall trait which is multiplication then we have our implementation block which implements the copy tree and this is for shape T so we're using the generic again and we're implementing it for our rectangle T and then we have this where statement and we're saying that the output of our multiplication has to be of type T so we're basically saying that okay our multiplication needs to be a consistent type with the fields that we have inside of our struct here when we actually create the function here we can still use generics like this like we've specified inside of our trade here and this will work so you can see here that we have integers and we have floats now if we try to put characters in here you'll see that we get an error because we can't multiply Z and C together there are various ways that we can actually write this here instead of using this where block which is much cleaner we could write it all inside of this here so you see here that I've put the output here and I have to open up another set of angle braces here and write output equals type T and we also have to implement the multiplication trait as well so what we're doing here is we're saying type T implements multiplication trait where the output equals T and it also implements the copy trade now the reason we're using copy is because we're using a reference here and then we're saying okay shape t4 rectangle T and then we just have our area here this becomes a little bit more problematic when we try to use like for instance a circle here we're trying to implement our generic trait for circle and this is working fine as it is right now we'll have an error now there when we start to try to work with a actual value here so if we multiply 3.14 one times our radius here the problem that we're having is that the compiler doesn't really know how to multiply this by our type T because our type T is still general whereas this is throat so there's a fairly complex way that we can actually get into casting and we can use macros to fix all of this but we're not going to go into that right now now it's important to note that when working with generics the type parameters often must use traits as balanced to basically stipulate what functionality type implements if a trait uses the addition then it requires T to be bound to the addition as well that is T must implement addition in this case because we have T implementing multiplication we can only use types that implement multiplication on their own so this allows us to bind say a rectangle to be of type number anyway guys that's all for now I hope you enjoyed this tutorial if you did feel free to comment and subscribe if you have any questions or comments feel free to leave them in the comment box below and if you just like this video then by all means download it as much as you like have a good night

Original Description

In this video we look at Traits and Generics in Rustlang. We talk about how we can use Traits to generalize behavior across data types and we look at how we can generalize types using generics. Feel free to donate: BTC: 1ExBSiaEa3pceW98eptJwzR9QHrYZ71Xit ETH: 0xE448a8DDA5886C49d35B191B2F20630c103024c8 LTC: LXsKxF5JhmMtKgqfcUFdvcXVwiaSqxN9cP Check out our Twitter: https://twitter.com/TensorProgram Check out our Facebook: https://www.facebook.com/Tensor-Programming-1197847143611799/ Check out our Steemit: https://steemit.com/@tensor
Watch on YouTube ↗ (saves to browser)
Sign in to unlock AI tutor explanation · ⚡30

Playlist

Uploads from Tensor Programming · Tensor Programming · 49 of 60

1 NodeJs, Text editors and IDEs
NodeJs, Text editors and IDEs
Tensor Programming
2 Vanilla JS todo App
Vanilla JS todo App
Tensor Programming
3 Elm Tutorial part 1
Elm Tutorial part 1
Tensor Programming
4 Elm Lang Tutorial, Part 2
Elm Lang Tutorial, Part 2
Tensor Programming
5 Elm Tutorial Part 3
Elm Tutorial Part 3
Tensor Programming
6 Elm Tutorial Part 4 -- Analog Clock App
Elm Tutorial Part 4 -- Analog Clock App
Tensor Programming
7 Elm Tutorial part 5 -- Snake Game
Elm Tutorial part 5 -- Snake Game
Tensor Programming
8 Elm Tutorial part 6 -- Calculator
Elm Tutorial part 6 -- Calculator
Tensor Programming
9 Go Tutorial part 1 -- Hello World and Static File Server
Go Tutorial part 1 -- Hello World and Static File Server
Tensor Programming
10 Go Tutorial part 2 -- Web Crawler
Go Tutorial part 2 -- Web Crawler
Tensor Programming
11 Go Tutorial Part 3 (Web App part 1)
Go Tutorial Part 3 (Web App part 1)
Tensor Programming
12 Go tutorial Part 4 (Web tutorial part 2) - Using templates
Go tutorial Part 4 (Web tutorial part 2) - Using templates
Tensor Programming
13 Go tutorial part 5 (web app part 3)
Go tutorial part 5 (web app part 3)
Tensor Programming
14 Go tutorial part 6 (webapp part 4)
Go tutorial part 6 (webapp part 4)
Tensor Programming
15 Go tutorial part 7 (web app part 5)
Go tutorial part 7 (web app part 5)
Tensor Programming
16 Go tutorial part 8 (Web app part 6)
Go tutorial part 8 (Web app part 6)
Tensor Programming
17 Go tutorial Part 9 (web tutorial part 7)
Go tutorial Part 9 (web tutorial part 7)
Tensor Programming
18 Go tutorial Part 10 (web app part 8)
Go tutorial Part 10 (web app part 8)
Tensor Programming
19 Go tutorial Part 11 (Web app Part 9)
Go tutorial Part 11 (Web app Part 9)
Tensor Programming
20 Go Tutorial Part 12 (Web app Part 10)
Go Tutorial Part 12 (Web app Part 10)
Tensor Programming
21 Go Tutorial Part 13 (Web app Part 11)
Go Tutorial Part 13 (Web app Part 11)
Tensor Programming
22 Looking at Elm 0.18
Looking at Elm 0.18
Tensor Programming
23 Go tutorial Part 14 (Web tutorial part 12)
Go tutorial Part 14 (Web tutorial part 12)
Tensor Programming
24 Go tutorial Part 15 (Web tutorial part 13)
Go tutorial Part 15 (Web tutorial part 13)
Tensor Programming
25 Go tutorial part 16 (web app part 14)
Go tutorial part 16 (web app part 14)
Tensor Programming
26 Elm Tutorial Part 7 (SPA part 1)
Elm Tutorial Part 7 (SPA part 1)
Tensor Programming
27 Elm Tutorial Part 8 (SPA Part 2)
Elm Tutorial Part 8 (SPA Part 2)
Tensor Programming
28 Electron Elm Tutorial
Electron Elm Tutorial
Tensor Programming
29 Go tutorial part 17 (web app part 15)
Go tutorial part 17 (web app part 15)
Tensor Programming
30 Up and Coming Programming Languages and Technologies for 2017
Up and Coming Programming Languages and Technologies for 2017
Tensor Programming
31 elixir tutorial part 1
elixir tutorial part 1
Tensor Programming
32 elixir tutorial part 2
elixir tutorial part 2
Tensor Programming
33 Elixir tutorial Part 3 (GenServer and Supervisor)
Elixir tutorial Part 3 (GenServer and Supervisor)
Tensor Programming
34 Elixir Tutorial Part 4 (GenStage)
Elixir Tutorial Part 4 (GenStage)
Tensor Programming
35 Elixir Tutorial Part 5 (Plug and Cowboy)
Elixir Tutorial Part 5 (Plug and Cowboy)
Tensor Programming
36 Phoenix Framework Tutorial Part 1 (elixir part 6)
Phoenix Framework Tutorial Part 1 (elixir part 6)
Tensor Programming
37 Phoenix Framework Tutorial Part 2  (elixir part 7)
Phoenix Framework Tutorial Part 2 (elixir part 7)
Tensor Programming
38 Phoenix Framework Tutorial Part 3 (elixir part 8)
Phoenix Framework Tutorial Part 3 (elixir part 8)
Tensor Programming
39 A Intro to Clojure and Clojure Syntax
A Intro to Clojure and Clojure Syntax
Tensor Programming
40 An Update about the channel
An Update about the channel
Tensor Programming
41 Intro to Rustlang (Setup and Primitives)
Intro to Rustlang (Setup and Primitives)
Tensor Programming
42 Intro to Rustlang (Strings, Tuples, Arrays, Slices and Pretty Printing)
Intro to Rustlang (Strings, Tuples, Arrays, Slices and Pretty Printing)
Tensor Programming
43 Intro to Rustlang (Ownership and Borrowing)
Intro to Rustlang (Ownership and Borrowing)
Tensor Programming
44 Intro to Rustlang (Structs, Methods, Functions, Related Functions and the Display/Debug Traits)
Intro to Rustlang (Structs, Methods, Functions, Related Functions and the Display/Debug Traits)
Tensor Programming
45 Intro to Rustlang (Control Flow, Conditionals and Pattern Matching)
Intro to Rustlang (Control Flow, Conditionals and Pattern Matching)
Tensor Programming
46 Intro to RustLang (Enums and Options)
Intro to RustLang (Enums and Options)
Tensor Programming
47 Intro to Rustlang (Vectors, HashMaps, Casting, If-Let, While-Let, and the Result Enum)
Intro to Rustlang (Vectors, HashMaps, Casting, If-Let, While-Let, and the Result Enum)
Tensor Programming
48 Rustlang Project: Snake Game
Rustlang Project: Snake Game
Tensor Programming
Intro to Rustlang (Traits and Generic Types)
Intro to Rustlang (Traits and Generic Types)
Tensor Programming
50 Intro to Rust-lang (Closures, the Box Pointer and Iterators)
Intro to Rust-lang (Closures, the Box Pointer and Iterators)
Tensor Programming
51 Intro to Rust-lang (Modules and Lifetimes)
Intro to Rust-lang (Modules and Lifetimes)
Tensor Programming
52 Intro to Rust-lang (Macros and Metaprogramming)
Intro to Rust-lang (Macros and Metaprogramming)
Tensor Programming
53 Intro to Rust-lang (Error Handling)
Intro to Rust-lang (Error Handling)
Tensor Programming
54 Intro to Rust-lang (Concurrency, Threads, Channels, Mutex and Arc)
Intro to Rust-lang (Concurrency, Threads, Channels, Mutex and Arc)
Tensor Programming
55 Intro to Rust-lang (Tests, Attributes, Configuration and Conditional compilation)
Intro to Rust-lang (Tests, Attributes, Configuration and Conditional compilation)
Tensor Programming
56 Rustlang Project: Port Sniffer CLI
Rustlang Project: Port Sniffer CLI
Tensor Programming
57 Rustlang Project: Chat Application
Rustlang Project: Chat Application
Tensor Programming
58 Rustlang Project: CLI Toy Blockchain
Rustlang Project: CLI Toy Blockchain
Tensor Programming
59 Intro to Rust-lang (Setting up a Development Environment)
Intro to Rust-lang (Setting up a Development Environment)
Tensor Programming
60 Intro to Rust-lang (Building a Web API with Iron)
Intro to Rust-lang (Building a Web API with Iron)
Tensor Programming

This video teaches the basics of Traits and Generic Types in Rustlang, covering topics such as operator overloading, iterator implementation, and bound generics. By watching this video, viewers can learn how to define shared behavior across data types and generalize types using generics.

Key Takeaways
  1. Create a trait using the `trait` keyword
  2. Implement the trait for a custom data type
  3. Use the `derive` annotation to implement traits for a custom data type
  4. Implement the `Add` trait to overload the `+` operator for a custom type
  5. Implement the `Iterator` trait to create an iterator for a custom type
  6. Use generics to reduce code duplication
  7. Derive the Debug trait to print out any type
  8. Use bound generics to specify a specific implementation
💡 Traits in Rust can be used to define shared behavior across multiple data types, and generics can be used to reduce code duplication and increase flexibility.

Related Reads

📰
What Is MLIR and Why Does It Exist?
Learn about MLIR, a intermediate representation for machine learning models, and its purpose in optimizing ML workflows
Dev.to · Fedor Nikolaev
📰
Why Choosing the Right Machine Learning Development Company Matters More Than the AI Model
Choosing the right machine learning development company is crucial for turning AI investments into measurable results, as it can make or break the success of AI projects
Medium · Machine Learning
📰
Data privacy in AI training: federated learning, differential privacy, and synthetic data
Learn how federated learning, differential privacy, and synthetic data preserve data privacy in AI training, and why they matter for secure machine learning
Dev.to AI
📰
Data Preprocessing: Encoding and Feature Scaling in Machine Learning
Learn to preprocess data by encoding and scaling features for better machine learning model performance
Medium · Machine Learning
Up next
Is Python Dead in 2026?| Truth About Python in AI Era | 90 Days Roadmap @FameWorldEducationalHub
FAME WORLD EDUCATIONAL HUB
Watch →