Rust Linz, July 2021 - Rainer Stropek - Traits, not your grandparents' interfaces

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
good chef what do you think should we start should we get started yeah we should okay hello and welcome to the second talk of the rust lintz meetup um we are really enjoying ourselves here at the sundeck of the grand garage and in the uh pause i already shared a short video a drone video which our friend rafael has shot and we will share more videos about how it is here in lint's life being at the meet up uh i hope the summer will be long and we will be able to do more in-person meetups here at the sundeck of the of the garage but now let's get into our second talk let me quickly introduce myself before i go right into the topic so let me switch it up here and here and now it is like it should be okay um i think a good idea is to introduce oneself let me quickly introduce myself to you my name is rhinostropic together with stefan i founded the rust lens meetup personally i am a passionate software developer i have been writing code for more than 25 years and i always say every day where i can write code is a good day unfortunately i can't write code every single day because if you work in it for a few years you have some management to do you have project management to do you have to do some some some sales stuff and so on but many days are for my personal life are coding days and i really enjoy that for more than 25 years i'm a microsoft mvp and regional director that does not mean that i'm on the payroll of microsoft not at all that means that i do just a lot of work with the community and if you do that you are promoted to a most valuable professional or original director that's all so to make a long story short beside my professional work i do a lot of trainings i am a part-time teacher i'm a mentor in the community i'm chairman of the coding club linds we run the local code of jalen's which is the programming club for kids here in linz and of course the rust links meetup that's essentially me and if you would like to get in touch with me on the right bottom side of the slide you see my digital business card just click on the link or type it in it's not that complicated and on the right lower bottom you find links to linkedin twitter facebook my youtube channel and so on and so on so i invite you to get in touch with me enough introduction let's take a look what we are going to do we are going to play tic-tac-toe i i said i love writing code and i learn most when i write code and one of the traditional thing that you build in a new language is a tic-tac-toe game and today we are going to build tic-tac-toe well it will be more of a code walkthrough because um so many things are here live here outdoor and so on so i wasn't i i wasn't brave enough to type the code live so it will be a code walkthrough and i will show you my points with existing code and of course i will over engineer the tic-tac-toe game a little bit because then with an over-engineered tic-tac-toe game you can learn a lot on the way of building this tic-tac-toe game we will learn some things about traits if you want to take a look at my code in detail i cannot talk about every single line in just an hour you can use this link that you find here in my slides and you can click on it go to github and take a look at it by the way i maybe should quickly share the link of my slides let me do that let me quickly go to slides.com here and have where is my this one and let's share this one this is the link you see this is the link and i will can i quickly copy that into the into the chat i think so i think i can do that live and here is the link it's in the youtube chat now so if you would like to follow the slides directly online you can now take a look at the youtube chat and there you find the link to my slides good without any further ado i would say let's get going thank you stefan please slide go to yes next slide okay internet is a little bit slow here so you don't see this funny gif here that's one of my favorite games when i was too too fast too fast too fast don't do the spoilers here just one this is one of my has been one of my favorite games when i was a kid anybody know this game prince of persia is exactly and you see this one is really the basic stuff we are just entering the first level we are opening a first door and that is a good thing to get started to talk a little bit about traits okay what is a trait let me quickly copy this one to show it to you life this is a very very simple example and in order for you to follow along is more easily i will go to the rost playground give me the rust playground here come on here it is and let me copy in these few lines of code that i have here and zoom in a little bit you know when i first i when i first played with rust and i read about traits then i viewed traits from the viewpoint of a c-sharp typescript developer kind because i write most of my days c sharp code typescript code sometimes a little bit of go code but to be honest i viewed it from the viewpoint of a c-sharp developer and when i when i found something like this as you can see it here pop trade computer get answer self whatever that self is self sounds like this and this arrow with u8 means we are returning probably a byte something like this this looks very much like an interface i know that in c sharp i would build a struct or a class i would create an interface something like this this could be a struct you could ask yourself why a struct without members yes that's possible that's definitely possible in rust that is called a unit struct and then you can implement as you can see it here you can implement a trait for a certain struct it looks a little bit different than in typescript or in c sharp it looks pretty similar kind of with go but it yeah it feels like an interface it sounds like an interface it smells like an interface i think i understood that that is fine and as you can see it here i can instantiate deep thought and i can ask deep thought for the ultimate answer and probably if i run this i will get 42 of course that's a very simple getting started that was my first introduction to traits but when i got more when i got more interested in the details let me try if i can zoom in a little bit i was asking myself okay what happens behind the scenes and if we take a look at the generated assembler code and i have copied it out here i used the type the rust playground to generate the assembler code what i essentially saw is that this interface was nearly gone it's not visible well it is kind of visible a little bit only in the uh in the in the names of the generated jump labels here but essentially it is gone if we call this method get answer which is a method from a trait then we essentially get a call assembler statement directly a call assembler statement with a static dispatch of this method really really simple so i think this is what many rust developers means when they say zero trust abstractions zero cost abstractions i'm very sorry they are trusted okay not not a good not a good phrase here this is what you can call a zero cost abstraction you can build interfaces and you don't pay for them at runtime that's a very good news okay now let's go into our tic tac toe game and take a look at basics applied to the tic-tac-toe game and then we work our way through to more complicated stuff because this talk is called traits are not your grandparents interfaces so obviously there has to be more about these traits let's take a look at one of my first things that i implemented here let me quickly look for the code that i would like to show you where is it where is it i'm going to find it and it's here let me zoom in a little bit so you see it pretty good close here you see a trait and in this case for demo purposes i created a structure which is called board content it will hold the data for my tic-tac-toe game okay it contains essentially a three by three so nine elements of size u8 array so eight nine bytes four three by three elements for our tic tac toe game and in this case i wanted to build an abstraction which i called to compact string which does nothing else than taking all these nine elements and turning them into a string very very obvious code even if you have not written a lot of rust before you will probably be able to understand this code from the context there is a lot going on here with traits but we will discover that a little bit later for now you see the board content which is my struct here you see the struct and you see the two compact string which is a trait and i implement this trait for my board content okay that should be pretty obvious any questions to this code maybe those of you who have not written a lot of rust code i know there are some people here in the audience who have not written rust code some of the beautiful things do you see the missing return statement yes i don't need a return statement you see i just write result without the semicolon at the end and that's the res that's the return you know what since i mix rust and c sharp i'm i'm i think people think i'm stupid whenever i give c sharp talks because i always forget the return statement i am i call myself a c-sharp trainer and i don't know how to write the return statement so if you see that if you see me doing that on stage now you know why i do that because maybe in the morning i wrote rust in the afternoon i write c-sharp and i always mix it up so this is rust this is interface this is traits and this is uh the first step let's go back to the slides and let's take a look at my second note yes let's take a look at a little bit more advanced example let's fold that one and let's take a look at this one let's make the font a little bit larger so everybody can see it properly here you see this one a square content it's an enum many of you know enums from many different languages and rust has enums too this is a so-called fieldless enum that means we don't have any additional data because in rust we could give additional fields to certain elements of the enum if we want to so we could say well in the case of an x i want to have additional data like a8 or a whole struct or whatever it could add additional data but i'm not doing that the first thing that you have to see and recognize here and that is pretty awesome see that one we can implement traits in this case this is a system trait the default trait that allows rust to understand what the default value of a type is i didn't define this trade this is this trait is system defined but i can define traits on enums that's pretty awesome in many other languages you can't do that additionally you might recognize that up here i have this strange thing hash derive with debug and copy and clone and partial equal and equal guess what all these things diva copy clone and so on are traits and what you see here in line four is the so-called auto implementing we can just ask ask rust to auto implement all these interfaces for us this is a macro so rust comes with macros and these macros can auto implement trades for us if they are pretty simple for instance there is a trait here copy which just says i can copy this data type by copying the underlying bits this can be auto generated there is no reason why i have to write code for that and this is the derive macro that you see here by the way if you want to know what's going on behind the scenes you can always copy this stuff go back to our good friend the rust playground paste it in and then somewhere i think it is here yes expand macros takes a second takes a second and here we are see this is the code that is generated no i will not walk you through this code you can do that experiment on your own but that's essentially what's going on behind the scenes auto-generating traits for your data types whenever they are pretty simple and when they can be auto-generated that's going on the first few lines of code here so you see a little bit more than just interfaces isn't it let's go further the next thing here is another system trait that i implement here you see square content is again our enum and this time i'm implementing the from trait from is typecasting if we want to have typecasting we implement the from trait so in this case i'm saying i want to be able to generate a square content from an unsight unsigned byte from eight bits and then i use the match statement of rust in order to turn the values of the unsigned eight into square content fields if the value is not available then we just panic oh my god i cannot convert that one okay the beautiful thing here is that there is a second trait which is called into it works exactly the other way around so what you can say you could say implement into for u8 for an eight by eight bit unsigned um eight bit unsigned byte uh to turn it into a square content so we have from in one direction and into in the other direction so which one should you implement and now comes the beautiful thing something again new for those of you who haven't looked so deeply into rust you get it for free if you implement from you get into in the other direction automatically without writing a single line of code if you are not an if you are not an experienced rust developer you can now ask yourself hmm how could that be how is that implement is that magic built into the rust compiler no it isn't i will show you the source code in the rust library in a few minutes where you will see how this magic is done how this works and guess what the magic is traits again tricks okay here you see yeah question oh very good question i will repeat this question question could i implement into and get from for free yes you would do that but it is um it is uh recommended that you always implement from and not into that's a kind of um yeah that's a kind of convention if you want in the standard stephen yes into is also for all yeah exactly that is what i meant with you get it for free i'm pretty sure i'm pretty sure i'm pretty sure i'm not 100 sure but i think i have to check it it's a good thing i have to check it but if you implement from what i said you get definitely into okay and just implement from that's the convention thank you stefan for pointing that out if i'm wrong i'm very sorry for that i always implement from so maybe i forgot something you see i wrote some type conversions and let me quickly go down here for those of you who have not written so many lines of rust code these are unit tests you see line 63 64 these are unit tests for the code that you have seen above and now we can take a look at how these traits are applied you see for instance take a look at this line of code here this one line 71 here i'm saying default default default is the name of the trait i can call here the method default and rust is smart enough to recognize that on the left hand side of this assert statement i have a square content and it automatically knows that it has to call the default implementation of square content in order to be able to compare both sides of the equation understood yeah there for the c sharp developers here in the room that would be the default keyboard in c sharp that would essentially do the same but here even that functionality is based on traits the default trait here you see the from and the into part let me quickly draw a little bit here here you see the from code where i convert a one byte into the square content and again rust is pretty pretty smart even with the even with the traits if i hover over the one here it recognizes automatically that this has to be an u8 because the front rate into the square content is implemented only for u8 so therefore i don't need to specify that this is a byte value i could do that but i don't need to let me quickly show you that come on internet wake up hello there is a short internet glitch here i hate that when that happens yes my wi-fi is suddenly gone luckily we are projecting from a different computer which which still has wi-fi so let me quickly switch to our second wi-fi i hope it will work we have three wi-fi's here just to make sure okay so let's see and it looks it looks good here we are here we are again very good we are online again stefan it is a good it was a good idea to bring so many wi-fi with us this is what i meant you see it oh it's a little bit slower here it's it's fine um here you see this is what i meant i don't need to add u8 rust is analyzing the traits automatically and it finds out that this u8 is not necessary because it understands that the from trait is available for u8 into square content and it does all the magic automatically okay and here you see that it works vice versa two one dot into i get it for free one dot into calls the front trade but the front rate is implemented in the other direction so it works pretty well raphael you have a question you want to know what happens if i for instance say something like i um i 32 something like this then we will get an error because let me hover over it there you see that there is no from i-32 trait so therefore rust cannot fulfill this magic no in rust type conversions are always explicit you don't get in implicit type conversion if the compiler cannot be absolutely sure if it is absolutely sure then you get it otherwise you have to explicitly write typecasts thank you for this question rawford so this is the into part next one is string i did the same for a character as you can see it here and just to to to add a little bit of extra for those people here in the audience who have not written so much rust code this is how you would write a unit test which is expected to panic it has nothing to do with the trait but i uh decided to just let it in here so you see it and maybe it's interesting for you i see some people nodding their heads i know you are c-sharp guys and typescript guys and so on so you have probably seen a little bit of frost but not so much so this is how it looks like so this was again a little bit of basics and with that i go back to my slide deck this is the wrong one this is the right one here we are we saw from into default everything's fine now let's go one step further and take a look at the board index class that i created not class of course a struct because we are talking about rust here what is the board index the board index is a struct here you see it which contains behind the scenes just a u-size value a u-size value is just an indexer in an array and the size depends on the machine machines register sizes in my case it's a 64-bit machine so it's a 64-bit value that you see here that's use size essentially and what i want to build is i want to build a secure way of indexing in our three by three board so i want to build an abstraction on top of view size that can only contain valid values between zero and eight nothing else and then i would like to build an index logic in our board where i can specify indexing a custom indexer with our own type okay so let's take a look at that one here you see this is our board index type the implementation is not that interesting because we want to focus on traits okay the implementation on of board index is not so relevant for traits so i will quickly go through that and go down down down here where we start to see again some of the traits the first traits are pretty obvious because you already learned about them i built a type converter from you size to the board index okay sorry the other way around this is what sorry i was confused this time i'm implementing an interface on a standard type you size to be able to convert you size sorry the board index into you size now i have it correctly sorry i was a little bit confused so i'm telling the system whenever you have a board index i'm clicking too much and it's too slow here so here we are whenever you have a board index and you need to have a u size you can directly take the inner value of the board index and return it so this is another takeaway that you can get a get from this talk you can easily implement traits on top of system data types in this case i'm implementing a trait for new size a type which i definitely did not implement on my own i can also add it to a string which is a rust string this is not a string that i invented i'm allowing here to turn a board in text index into a string by just formatting it as a number nothing special here the other way around is just calling a method this method method checks whether the value is between 0 and 8 that's fine and i also do some parsing how does parsing work ix is a string and now suddenly rust knows that parse has to parse a value and turn it into a board index how does it know that i invented the logic that a board index is represented by a string combination like a1 or a3 or c2 how can pars know what to do now what is the talk about traits therefore it knows it because we have a trait there is a system trait which is called from string and from string essentially powers parsing so if you implement the from string trait for a data type in this case a static string i just implemented here for a static string and then i can write some parsing logic and here you see i will not go into the details because this is just rust and if you you're not familiar with rust you can take a look at the code afterwards the essential thing that i want to tell you here is that this again is a trait and by implementing this system trait i get the parse statement for free it knows that it has to call the from string trait in this case the from string implementation so to turn everything into a valid board index some of you might have a little bit of problems here because you you might ask yourself here what is this result all about that's essentially a data type in rust where i can specify that the result can be either self in this case the board index so i successfully created the board index from the string or i create an error type result is an enum and this enum has two possible values okay and error okay would be that one and if i scroll down a little bit you see this is the happy case and this is the second one this is the error case this is where you have something like this so this is how the from string the from stir trade works you just return either the okay happy part or the error depending whether you could parse the value and everything is built on top of this trait let me quickly take a sip here and wait whether we have some questions matthias asks any reasons why you didn't use rust stock three slashes here in this case it's not really matthias it's not really a documentation for this trait it's just notes for me to remember what i want to tell you so matthias is perfectly right rust stock the correct way of writing documentation in rust is with three slashes and not two slashes but these are just my personal notes not documentation we have a video i think stefan in our library where we had a full hour talk about how to create awesome rust documentation so if you are now confused by me doing it not right take a look at this video uh we this video is awesome you will really learn a lot in this video check out rustlings80 you will find it there but thank you matthias for pointing that out let's scroll down a little bit and we have a new trait of course straight straight straight the display trait what is the display trait all about the display trait is the trait that is used by the print line macro or the format macro let me quickly scroll down a little bit and let me take a look do i have a unit test for that yes i have a unit test for that you see this one this is the using of the display trait whenever you use the print line macro or the format macro to turn a board index into a string and you use this curly braces opening close thing here rust knows that it has to call the display trait in order to turn the board index into a proper string in our case a1 b2 c3 something like this there is another trait with this which is important in that regards it's the debug trait you can auto implement it or you can implement it by hand and this is used whenever you use the colon question mark syntax to to print the debug output of your value okay that is a different trait but in this case we are talking about the display trait this is another important one that we have in this example display trade last but not least we have two interesting ones add and sub again two system traits and these system traits power what what do you think plus and minus they are powering operator overloading so you have to implement a trait and in order to be able to use the plus and minus operator so in this case i'm implementing add and sub on the board index so that i can add and subtract board indexes from each other let me scroll down a little bit and see whether i can find whether i can find the prop yeah here you have it you see here in this case i am taking a board index and i'm adding uh let's hover over it use size on top of it and the result will be another board index and here i can subtract from something from my board index in order to reduce my board index and the result is again another board index so if you want to have operator overloading in rust implement system trades and then you get support for the plus and minus operator out of the box so you can already see that tr that that traits are very very deep into the ecosystem of of rust whenever you write rust code you have to deal a lot with traits other languages like c sharp a language that i know for more than 20 years i think they are doing it completely different they are having for instance static members on types where you can do operator overloading completely different address like rust does it here by the way if you ask yourself hey rhino what is this stuff this has nothing to do with traits this is a very interesting crate it's a kind of library which is called rs test rs is not my name it's not rhinostropic i have not written it yeah somebody else has written it and it's essentially data-driven unit testing you can easily write data-driven tests like this in rust it works like a charm i really like to use it and i think even those of you who have not written so much lines of code in rust you will guess you will be able to guess from the context what this stuff is all about nice so let's go back to our slides and let me check yeah i promised you that we will take a look into why we get this into for free if we implement from and what i did is i looked up the relevant code piece in the rust library in github and here you see what the magic what the magic does take a look at that one and that is pretty awesome and pretty different to many other languages latest here at that point in time you should understand that traits are way more than the usual interfaces you might know from other languages take a look at this type this is an implementation of the into trait for any type t line 45 here where sorry for any type u where u implements from so essentially into is auto implemented for any type offering from by just calling from in the other direction so you can implement traits on top of other traits you don't need a concrete data type trait in german means fair cat so you can derive a trait from another trait let me say one german sentence here so that it's very clear for the audience and if fake head of pass is an underinflate this is what you essentially do here and by having this line of code here we get into for free when we implement frau pretty nice isn't it okay very good back to the slides did i forget anything no let's continue boards content showed you that we have a trait there which is called two compact string let me go back to the board content here it is i implemented to compact string and i implemented it on top of board content but i asked myself what can i show you more how can i show you what we are capable of doing in terms of doing more powerful abstractions and here i have added a second trait board it to compact string which is very similar to the two compact string trait but this time i am it's the same signation you see it i can copy it to i can turn it into a compact string representation but this time i'm implementing it on top of you see it here an iterator over an array so i'm no longer implementing the trait for a concrete type like the board content struct but i know i know that my board content internally has a static sized array nine elements therefore it is very simple to implement an iterator essentially the array already implements an iterator and if i have an iterator i can abstract my trait board into the compact string away from the board content and build it on top of the iterator over the array and therefore my trait implementation is now more flexible it works works with any iterator over any nine element array here it doesn't need to be my board content it can be your board content as long as you can provide an static iterator array sorry a static iterator over an array you are fine my implementation will work for you so this is the application of this building a trait on top of a trait now not in the standard library but in my own application i can make my implementations more flexible i can make it more widely usable that's the idea here it's just a demo so don't ask for the why is this really a good idea is this the best design probably not but i want to showcase some of the features what you can do with traits okay that's my point here so let me take a sip of water here and wait for any possible questions okay good no questions currently so i think you want to know more good i just opened pandora's box of the entourage no it's not pandora's box it's a it's a huge cake a huge a huge playground iterators are awesome in rust i come from a world of i mentioned that before c sharp and in c sharp we have an awesome functionality which is called link i love it language integrated query it's so awesome mapreduce if you are a javascript developer and in rust it's iterators on top of iterators you can do all the crazy stuff like mapping and filtering and summing and all this stuff is built on top of iterators so let me quickly show you how we can turn our board content into an iterator that's pretty simple we can for instance implement the trait into iterator for our board content and then this into iterator trait has something unique which is again very special for rust and i don't know this feature from other interfaces from other implementations of interfaces in other languages in this case we have let me draw a little bit here we have parameters for traits so the into iterator trait demands two parameters you have to tell it okay what is the type that we will get back item by item and secondly you need to specify and a structure that you will use as your iterator because the iterator is represented by a structure by a data type if you turn if you create an iterator you are essentially creating an instance of a struct and you can choose this struct you can choose which struct you want to use in this case i'm just using the existing struct of the underlying array so i'm using the array into it and i'm just asking my internal array for its iterator and i'm just returning it and with that i offer the array iterator on top of my board content in a second you will see that we can build completely custom iterators which come with with complete custom iterated types you will see that in a second but in this case i'm just saying i am hiding the implementation from outside but i'm passing on the existing iterator logic by using the existing array iterator and just returning it here by implementing this into itatrade and when i have that one i can for instance use a loop statement to iterate over my board content understood okay sounds like one sounds like haskell was the comment i have no idea because i've never written a single line of haskell i believe you i absolutely believe you let me show you what we can do with that if we take that one step further i have implemented here here you see it a bunch of types in order to be able to show you how you can build a completely different iterator in my case i want to implement an iterator which allows me to iterate over the rows of my board remember i don't have a two-dimensional array i have a single dimensional array which with just nine elements in it and i want to build an iterator a virtual iterator which iterates over rows which do not really exist there is no data structure internally that has rows so how can i do that first i implement the structure which is called row this is a small data type which holds a reference a pointer to the underlying board content and the row index a pointer and an index you might ask yourself what this funny thing is like this is the so-called lifetime is that it has nothing to do with traits it is a different topic for a different talk just so much you need the lifetime here because rust needs to understand that the row can never outlive the board content that it cannot happen that you have a board in your hand and you already destroyed the underlying board content in c sharp i could do that and if i do that and i try to access the underlying content things would go horribly wrong in rust the compiler is smart in rust the compiler has these lifetime annotations and with that it doesn't need a garbage collector and it can still prove mathematically proof that it will never happen that you have a role that outlived the underlying data type this is what lifetimes are all about you can use lifetimes in traits definitely i will not go into the details here but i just want you to be able to follow what i show here so if you ask yourself what is this this is a lifetime annotation i'm binding the lifetimes of these two things together now i have a bunch of implementations that is not that interesting i will go down here because because now it's starting to become very interesting now i start to implement the rows iterator the rows iterator is essentially an iterator which again holds a reference to the board content and the next row and the interesting part comes here where i implement now the iterator trait which is the standard iterator trait for my rose iterator and the only thing that i have to in the background implement is the next method this is how iterators work in the background the system which will just call next over and over again and i can write my own custom business logic and what i have to return is an instance that will get that i will get back from this iterator so if i run through the rows iterator i will get one row instance you saw it before one after each other i'm just maintaining a counter here and i'm adding one to the counter whenever i call next if i'm at the end i just return none if you are new to rust none is rust's null there is no null in rust rust has the option type and the option means either i have something for you or i have none there is no possibility for null null is not supported at least in a safe rust context and we are not going to talk about this ugly unsafe stuff which we are no we are not going to talk about that that's a completely different talk so you see you can easily implement these iterators now what does this give me let me quickly jump back to my board content and scroll down to a nice little piece of code which i have where do i have it no i'm in the wrong file here is this nice little code this is what are we fighting for see that one four row in self dot rows rose returns the iterator that you just saw and because this is a system trait my iterator is capable to work with a for loop so by implementing this iterator trait the for loop now calls my next method and every call to the next method returns an instance of the row and then i did the next interesting stuff see that one i'm able to index inside of the row by using this indexer down here so the square brackets and that will be the column inside the row and that will be the next trait that we are going to take a look at the index trait but i hope you understood now that this is pretty awesome and by having this iterator support i get really really strange things i can for instance say see that one hey give me the nth row inside my board this is a feature this is a functionality that i get out of rust's awesome iterator logic you could do give me skip some elements or take some elements or filter some elements or map some elements and in this case i just use the nth operator this will give me the first in this case it starts by zero so the second row by just calling my next method two times and give me the second row so by implementing this iterator trade i open the whole possibility that rust brings which with its iterator library okay and this is a completely custom implemented iterator nothing but nothing uh standard iterator stuff it's completely written from scratch with my rose any questions so far good nice i promised you indexing i promised you indexing and indexing is here let's do that way okay this one and this one these are two additional traits that i want to talk a little bit about the index trait enables us to access our data structure with the square bracket syntax it allows us to build a custom indexer the first one you see it here receives a reference to self to board content because this is the data type that i want to be able to index and because it just says is a reference to self it's a read-only reference if you take a look at the index mutable down here this is the second trait i would like to mention you just write reference mutable self and that means i can write into self into my own data structures and this is a deep immutable that's not a shallow immutable but if i have a immutable reference i cannot manipulate whatever i have and whatever whatever is inside of my my own again there is there is rust magic with which you can allow certain things but the default uh behavior is exactly like that it's a immutable version of myself and i cannot manipulate myself so i can only return as you can see it here i can return an element from myself but if i take a look at the index mutable here i can return a mutable reference to an element of myself don't get me wrong the index mutable is kind of interesting it doesn't do the writing the index mutable trait takes a reference which points to some data structures that i internally use and gives back to the caller a so-called mutable borrowed reference so the caller gets a reference that the caller can use to write something something into this memory understood that is what index mutable is all about and if you ask yourself oh rhino what can that happen with with parallel oops then what can happen with parallel programming do i need to worry about some some some some race conditions and things like that no you don't because the ownership and borrowing system of rust protects you from shooting yourself into the knee yeah the ownership borrowing concept is again a very good topic for another day for another rustlings meetup i'm not going to talk about it but just trust me and believe me if you build safe rust not unsafe rust you don't need to worry about parallel programming and about data races and things like that these things are gone they are no longer present without the garbage collector and without without a heavy weight runtime that's the awesome thing of rust that's the magic of the of the rust compiler okay so index mutable goods yeah that is not that interesting i had some indexer and that's good and last but not least before we go into the last few minutes i think i have i know 10 minutes left or so and then i'm done um let's take a look at game game is another interesting thing maybe it's interesting i'm not sure i hope it will be interesting for you what i did here is i had another idea for something that i can show you try to concentrate for the last few minutes here you see i invented here you see it a trait which is called square assessor it allows me to access a square inside of a tic-tac-toe board and i implement two different methods get and set i think it's pretty obvious what this thing does right pretty clear not very difficult for those of you who are quick and who take a close look at my code you will probably already have recognized something up here see that one mock all auto mock does that ring a bell to you of course we can use traits for mock objects for unit testing and i will show you that in a second this is why i implemented this trait this trait is mockable and this nice little crate crate is something different than a trait okay for those who are new to rust the crate is like in c-sharp a nougat package or in javascript an npm package or in java oh my god i have no idea from java maven did i say something wrong no not really kind of let's not talk about java nougat an npm i'm sure about that a crate is the same in rust and mock all is a crate a nice crate for mocking and here i'm telling this mock all crate to auto implement a mock object for my trait which i can later on use for unit testing okay you will see that in a second but the second important thing here you will see that here is this line i now implement the square assessor not on top of my board content because i don't need a board content for that i implement it on top of any data type that supports indexing via a board index this was the save index that we built together and that returns a square content so if you want to build a data structure with a backing vector for your tic-tac-toe game feel free to do so as long as you allow me to index with my board index and you return square content i am fine my game controller will still work on top of it so again an application where i implement the trait on top of another trait instead of implementing an interface on a concrete class or structure get it clear awesome and with that i can do crazy stuff something like let's take yeah let's take this one this checks um a method which is called is valid it just checks whether it can never happen that we have two x's and no o's so a player has set two times and the other one has never set something like this is discovered with this valid but in this case i would like to implement to test this logic of is valid without having a real board content i'm using the mock version of my square assessor you see it here this struct mock square assessor was not created by me this is the result of the auto mock macro that you have seen before it took my trait my ssr my square esseso trait and created the structure which is called mock square assessor and i can then mock for instance the get method and implement some lambda function here which is called whenever the get method is called and in this case i'm just returning um x then o then x then o so this will be a valid board so i can assert down here that is valid really returns true that is my unit test and if we take a look at the second test here this is the error case in this case i make sure that this board is not considered to be valid because in this case i'm returning a given value x or o two times and all other elements are empty and that's not allowed because then x has shot two times or o has shot two times and the other one has never shot and that is not a valid tic-tac-toe board the business logic is not the point the point that i want to make here is really the possibility of implementing traits on traits and of using traits for mocking you might ask yourself can i use structs and mock based on structs yes that's also possible so auto mock allows you to build mock structs on top of other structs that's possible and in some cases you really need that for instance i do some work with a rocket framework which is a framework for building web apis in rust i really like it i've done a talk at the roslins meetup about it and whenever i have to do unit testing with mock objects for instance to mock away my database or backend micro services i need to apply auto mock on top of structs awesome good you have learned a lot and we are already nearly at the end but i would like to show you one last thing a one last look behind the scenes i would give you this magic sword that you just saw here and i will not show you that in details because i have prepared it here in my slides come on internet show me my next slide oh isn't that nice you can really read it very nicely no probably not so i will zoom in a little bit i want to show you what's going on behind the scenes when you implement some traits on top of a structure let me go up here a little bit and then it should be readable hopefully it will be yeah i think you can read it properly is that okay i think it's it's okay please jack that here i have implemented two structs cat and dog and i have implemented the trait the trait animal now here i have implemented a function which takes an animal and please recognize the impul keyword here i essentially say the print sound method should be applicable to any animal anyone who implements an animal can call print sound now the interesting thing here in this last demo of my talk today is what's happening behind the scenes in assembly language in assembler language we get two different copies of our print sound method the process here is called monomorphization so it duplicates the necessary functionality in assembler language so that we don't have to pay with a dynamically dispatched indirect function call we get a static dispatched function call one version calls the dog one version calls the cat and of course aesthetically dispatched call is really really fast so by calling you see it down here again by calling print sound with cat and dog you see it on the left lower corner here i do monomorphization and duplicate the code so i get better performance but i get a little bit larger code base this is what's happening when you use this input keyword you cannot use input always in some cases it's not possible and then you need the second keyword and that will be really the last keyword of my presentation today and that is the dun key word dynamic dispatch that's essentially exactly the same code that you have seen before the only difference here is that now i'm using here the din keyword what i get from the dun keyword is a so-called trait object technically i get a kind of v table a table with virtual function pointers and the method dispatching is done through the b table so in this case again i call print sound for two animals cat and dog but see it up here it calls the print sound method in assembler language and the print sound method in assembler language up here i copied it out here i don't have two print sound methods here i just have one print sound method here and this print sound method makes an indirect function call through the v table and of course that is slower but i don't need a duplication of the methods here i don't have monomorphites monomorphizations there are a lot of situations where you need this trait objects and i cannot go into the details here because this is not a training this is just talk and i limit myself to one hour so i'm just can give you the facts and you have to read up the details when you have to use trade objects and when you can use the impul keyword the compiler will tell it to you so if you try to use impul where it doesn't work it will tell you used in and if you use dun and you use it in the wrong way for instance if you need to create it a box and put the den in it trust the rust compiler the rust compiler will lead your way you will love it hopefully maybe you will hate it sometimes but the rust compiler is always right it will guide you away that's the beauty of the rust compiler okay that was a lot of content for one hour but i wanted to give you an idea what traits really are and that they are more than just interfaces i think traits really rock what are the most important things that you should take away you should take away that traits are one of the underlying major concepts of the rust programming language type conversion operator overloading iterators everything is built on top of traits you get zero cost abstractions through monomorphization or if you don't need monomorphization the trades you don't have to pay for the trades at run time yes dispatching dynamic dispatching is possible with the keyboard but it's not a must it depends on the situation and on your code i hope you found this one our interesting i hope you enjoyed today's rust lintz meetup we will be pretty at the we are now pretty at the end of our rust meetup it's getting dark now the video pima now works perfectly fine before we uh go to the fridge and take a last drink and maybe talk a little bit chat a little bit about what we've heard today about your experiences let me ask you do we have any urgent questions that we should discuss before we get some additional drinks and eat the rest of the fairy's cake you
Info
Channel: Rust
Views: 6,645
Rating: undefined out of 5
Keywords: rust-lang, rust, rustlang
Id: B0fL3WmJZsc
Channel Id: undefined
Length: 61min 35sec (3695 seconds)
Published: Mon Sep 06 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.