Minor correction: In the last example you change the signature of animal_sounds to take a shared slice (often just called a slice) of Animal trait objects, not a reference to an array. A slice [T] is dynamically sized while an array [T; N] is fixed-size.
I was confused by exactly this part in the video and your correction was extremely helpful as I'm just learning rust and your comment made me go from "I still don't get Rust" to "seems I learned something at least" 😁
would you be kind to explain with an example what exactly its wrong there in the animalsounds, what I understood is instead of a ref to vector he is providing a ref to array , something from high level programming language like giving super class type instead of subclass type !! crrct me if I am wrong :)
@@bjugdbjk Yes, the code in the video is correct and considered idiomatic, but Let’s Get Rusty makes a mistake in calling &[Box] a “reference to an array” of Animal trait objects. This is called a “shared slice” of Animal trait objects, but usually just called a “slice” of Animal trait objects. Slices are a dynamically-sized view into a contiguous sequence of elements in memory, while arrays are a fixed-size collection of contiguous elements in memory. With function arguments, a slice is more generic than a Vector because both Vectors and arrays can be coerced into slices, which is demonstrated at the end of the video. A slice is not a “super type” of Vectors and arrays in the OOP sense (Vectors and arrays don’t extend the functionality of slices); Rust does not have inheritance. Instead, both a Vector and an array can be coerced into a slice because their elements are contiguous in memory. Coercion can be confusing when learning Rust because it’s handled implicitly as a convenience when most things in Rust are explicit. I encourage you to read an article online called “What Can Coerce, and Where, in Rust”, especially the section on slice coercions. I hope this helps!
I would have also mentioned the AsRef trait, as it's a common way for functions to generically accept both owned and borrowed values as arguments. In Rust generics are monomorphised at compile time so it's zero-cost as well.
@@dragonmax2000 The function just prints whatever it is passed. So it can take anything that can be printed by the println! macro, not just strings. In Rust, that can be expressed as impl Display.
I found this video very helpful. Doing Advent of Code, my functions and methods were a bit over explicit, especially taking references to vectors. My question is if there is any coersion overhead, but I'll look it up. Your video pointed me in the right direction, thanks
How do you make a type corerse (used often in the video, don't know what it means)? I understood that a type is then applicable for another type. But how can I implement that behavior for my own types?
Since the author didn't seem to answer questions, you need the Box because the vector contains dynamic traits, so the compiler doesn't know at compile time what the items will be, nor their size, and it's not possible to iterate or even to store such diverse items with an array. So instead, it's an array of pointers to those items. And since they're traits and not objects, they're also accompanied with a vtable (a table with a pointer to the functions of the trait - here, speak). So we see that using that sort of polymorphism has an additional cost.
Coercion is the rust type system realizing that a type can easily be converted into another type. It then allows you to transform it automatically. You know how in rust, sometimes you can declare a type as (like Vec) and itll automatically determine the type? It's like that, except it will check if a type can become another type if there's a type mismatch. I don't know the answer to your other questions so sorry if this isn't super helpful!
Coercion is automatic conversion of one type into another. You can make a type coerce into another by implementing the Deref and DerefMut traits. For example String implements Deref and Box implements Deref Other cases of coercion include: &mut T into &T (a mutable reference can be used as immutable reference) &T into const* T (a reference can be used as raw pointer) Non-capturing closures into fn function pointers ! (the never type) into any other type (this is why you can write a match statement, where one of the branches panics and ever returns a value)
So the signature would be "animals: Iter" and you call it with "animal_sounds(animals.iter())". It all depends what you need to do in the function. You don't have access to any of the Vec methods anymore, like for instance "contains" that looks for a specific item. But it is more general with Iter since you can call it with anything you can transform into an Iter.
If I recall, Clippy will flag up not using String and Vec coercion. I started using String and Vec arguments when learning. Then switched to string and array slices. But I'm not quite sure whether I read this beforehand or if Clippy told me!
The point is to be as general as possible but not more. Javascript will allow you to pass something in which is e.g. is not printable which breaks your code. Let's say you write a job offer for a company, you don't want to write "looking for a 47 year old west Spanish man with green hair who can cook Spagetti with the left hand" (first code) because it's too specific but you don't want "any living being" either (Javascript), instead you want "someone who can cook spaghetti" (code at the end). If it was never worth it to have types then typescript would never have been invented 😁
📝Get your *FREE Rust cheat sheet* :
www.letsgetrusty.com/cheatsheet
Minor correction: In the last example you change the signature of animal_sounds to take a shared slice (often just called a slice) of Animal trait objects, not a reference to an array. A slice [T] is dynamically sized while an array [T; N] is fixed-size.
Just to add: fixed size arrays can be coerced into dynamically sized slices of the same type, which is why it worked.
I think this correction is major enough to want to annotate the video.
I was confused by exactly this part in the video and your correction was extremely helpful as I'm just learning rust and your comment made me go from "I still don't get Rust" to "seems I learned something at least" 😁
would you be kind to explain with an example what exactly its wrong there in the animalsounds, what I understood is instead of a ref to vector he is providing a ref to array , something from high level programming language like giving super class type instead of subclass type !! crrct me if I am wrong :)
@@bjugdbjk Yes, the code in the video is correct and considered idiomatic, but Let’s Get Rusty makes a mistake in calling
&[Box]
a “reference to an array” of Animal trait objects. This is called a “shared slice” of Animal trait objects, but usually just called a “slice” of Animal trait objects.
Slices are a dynamically-sized view into a contiguous sequence of elements in memory, while arrays are a fixed-size collection of contiguous elements in memory. With function arguments, a slice is more generic than a Vector because both Vectors and arrays can be coerced into slices, which is demonstrated at the end of the video.
A slice is not a “super type” of Vectors and arrays in the OOP sense (Vectors and arrays don’t extend the functionality of slices); Rust does not have inheritance. Instead, both a Vector and an array can be coerced into a slice because their elements are contiguous in memory. Coercion can be confusing when learning Rust because it’s handled implicitly as a convenience when most things in Rust are explicit. I encourage you to read an article online called “What Can Coerce, and Where, in Rust”, especially the section on slice coercions. I hope this helps!
That concept of least indirection is really useful to me.
I would have also mentioned the AsRef trait, as it's a common way for functions to generically accept both owned and borrowed values as arguments. In Rust generics are monomorphised at compile time so it's zero-cost as well.
You can use AsRef instead of &str. AsRef can handle owned type without referencing.
Back to the basics. I like it!
Also, the argument of the first function could've been impl AsRef. Or even impl Display
Would you be kind to elaborate on the Impl Display, please?
@@dragonmax2000 The function just prints whatever it is passed. So it can take anything that can be printed by the println! macro, not just strings. In Rust, that can be expressed as impl Display.
Great video. Showing 2 different approaches and which one is better and the reason, is a very good way of teaching.
I found this video very helpful. Doing Advent of Code, my functions and methods were a bit over explicit, especially taking references to vectors. My question is if there is any coersion overhead, but I'll look it up. Your video pointed me in the right direction, thanks
As always clear and crisp with meaningfull examples. Excellent job!
Really useful. Definitely reduce some headaches trying to reference different types of strings etc
Great video as always, but all those popups and hints and suggestions and messages and things-you-did-not-write simply drive me crazy! :-)
Awesome, very illuminating!
Man working with boxes and "dyn" is so unsightly- I avoid it as much as I can just due to readability. Great vid tho
I agree, but it's not something that can be avoided if you need dynamic dispatch, is it?
3:25 you had such a good opportunity to sneak in a Beach Boys reference. Oh well :-|
Super helpful and clear - thank you sir!
Very clear on coercion. Thks B man.
What is your vs code setup for rust?
How do you make a type corerse (used often in the video, don't know what it means)? I understood that a type is then applicable for another type. But how can I implement that behavior for my own types?
Not overly experienced in Rust myself but you might be able to do this by implementing the Into trait.
what plugin are you using that makes the type annotations?
Also you can write println!("{dog:?}"); instead of println!("{:?}", dog);.
really?
@@v0xl Yes
This is a great set of video's. i love what you are doing.
Could you have use an iterable for the vec function ?
This video is really enlightening
Can you remove the box in the array of animals func arg? if so why not?
Since the author didn't seem to answer questions, you need the Box because the vector contains dynamic traits, so the compiler doesn't know at compile time what the items will be, nor their size, and it's not possible to iterate or even to store such diverse items with an array. So instead, it's an array of pointers to those items. And since they're traits and not objects, they're also accompanied with a vtable (a table with a pointer to the functions of the trait - here, speak). So we see that using that sort of polymorphism has an additional cost.
So what does coercion do? Is it syntactic sugar?
How can I make something coerce into something? What other types coerce into what?
Coercion is the rust type system realizing that a type can easily be converted into another type. It then allows you to transform it automatically. You know how in rust, sometimes you can declare a type as (like Vec) and itll automatically determine the type? It's like that, except it will check if a type can become another type if there's a type mismatch. I don't know the answer to your other questions so sorry if this isn't super helpful!
Coercion is automatic conversion of one type into another. You can make a type coerce into another by implementing the Deref and DerefMut traits. For example String implements Deref and Box implements Deref
Other cases of coercion include:
&mut T into &T (a mutable reference can be used as immutable reference)
&T into const* T (a reference can be used as raw pointer)
Non-capturing closures into fn function pointers
! (the never type) into any other type (this is why you can write a match statement, where one of the branches panics and ever returns a value)
@@KohuGaly thanks, this is helpful
@@KohuGaly A small error but const* T should be *const T
wouldnt it be better to turn the vector into some sort of iterator type instead of an array? sorry if its a silly question, im pretty new to rust
Another rust beginner here and I wonder about that as well so good question 😁
So the signature would be "animals: Iter" and you call it with "animal_sounds(animals.iter())". It all depends what you need to do in the function. You don't have access to any of the Vec methods anymore, like for instance "contains" that looks for a specific item. But it is more general with Iter since you can call it with anything you can transform into an Iter.
Can you explain static functions in rust sometime?
Awesome video as always dude, keep it up!
Very useful! Keep up the good work.
Awesome video. Keep them coming.
Very nice :) Thank you!
Thanks, that was useful!
Does the vector have to be the same length?
Same as what?
@@DanielTredewicz same length as the array
I wish IDEs would be less eager to show doc pages and compilation errors while still writing!
O_O I knew about String coercion but not Vector and Box
If I recall, Clippy will flag up not using String and Vec coercion. I started using String and Vec arguments when learning. Then switched to string and array slices. But I'm not quite sure whether I read this beforehand or if Clippy told me!
Great vid
The function can take more types...well in Javascript any function can take any types...is it worth it?
The point is to be as general as possible but not more. Javascript will allow you to pass something in which is e.g. is not printable which breaks your code. Let's say you write a job offer for a company, you don't want to write "looking for a 47 year old west Spanish man with green hair who can cook Spagetti with the left hand" (first code) because it's too specific but you don't want "any living being" either (Javascript), instead you want "someone who can cook spaghetti" (code at the end). If it was never worth it to have types then typescript would never have been invented 😁
Not sure if you should really put the cat or dog in a box. They probably won't like it...
What are you talking about? Cats love boxes.
@@31redorange08 cardboard boxes maybe. Not sure about rust boxes.
Is there any framework is under development in rust for fuchsia os?
Love your channel mate, btw I stand with Ukraine ♥
Rust is big wee-wee energy
Pew pew pew
Good videos, but the excessive autocompletion and checks that your extension is doing is EXTREMELY annoying.
I see what you mean, useful but not for presenting...
Should probably disable for teaching/presentation purposes.
// for algorithm