Transcript from the "Numeric Types & Type Annotations" Lesson
>> So let's talk about numeric types. So here I've said let mut y =2.2. And then later on I've said y = 3.1. And then let's suppose right after that I said y equals the string 3.1. So this would not work because in rust, although you're allowed to reassign things, once you define a value, that value gets a particular type associated with it.
[00:00:23] And you're not allowed to change that at runtime. Even though you're allowed to reassign values of the same type, you can't change to a different type. So this would be an example of changing from a float to a string and that's not allowed in rust. Now, we didn't have any type annotations in that example.
[00:00:41] But if I wanted to, I could add a comment here, this is a comment and rust say, hey, by the way, x is a float. But really I would never do that because what I would do instead is I would actually write a type annotation like this saying x colon f 64.
[00:00:52] F64 is short for 64 bit floating point number. So we'll talk about the different numeric types in a second. But basically the reason that I might do this is I might want to be explicit about the type of x. Now you'll notice that I didn't have to do this.
[00:01:09] So there's plenty of languages where you have to write out the types of absolutely everything. In rust, at least when it comes to let, you don't have to do that. Rust you'll be able to do type inference and generally speaking be able to figure out that okay, I see that you assigned X to 1.1.
[00:01:22] That's some sort of floating point number, okay, no problem. You don't actually need to write out the f64. And in fact, if I want to, I could write it out for x but not for y. That's another thing I could totally do. But importantly, it doesn't always get that, it's not always able to provide that.
[00:01:39] So in some cases rust type inference when you get into more complicated types probably won't actually happen in the course of this workshop. But as you get more advanced rust, sometimes when you write let, rust compiler will say, okay, I need to write out the type annotation because I can't quite figure out what this is.
[00:01:54] But it's important to note that it'll never get it wrong. Like it'll never miss infer something and say like, yeah, I know what the type is. And it actually is a different type. The worst that will happen is either it'll get it right and say, great, I was able to infer that or it'll say, hey, I couldn't figure this out, I need you to write out the type annotation.
[00:02:12] So the compiler is at least reliable when it comes to that even if it's not 100% able to always offer that. So let's look at defining our own functions. Let's say I want to say let answer equals then call a function called multiply both passing two floats and then print the answer here.
[00:02:30] Here's how I would define that function, say function multiply both x is an f64 y is an f64 and it returns an f64. So here although main didn't have any arguments multiply both is taking two arguments. Now when you're defining functions, you do have to write out the type annotations always, that's a rule in rust.
[00:02:49] So if I'm saying multiply both is a function that takes x and y, I do have to say what their types are. And then I also have to say what the return type of the function is. And then I can use the return keyword to say return x times y.
[00:03:01] So you can read this type annotation here as multiply both takes two f64 arguments and returns an f64. Whereas main takes no arguments and returns nothing. So if your function doesn't return anything, you don't have to put this arrow here, you can just leave it off. Okay, we did talk about the difference between, macros and functions.
[00:03:22] But here we can actually see in the way that we're calling multiply both, we're not using the exclamation point here. So this is the first time that we've seen something without that exclamation point. But in normal rust code, this is way more common. And the exclamation point is only used for the occasional macro, which definitely come up plenty often, but not nearly as often as normal function calls.
[00:03:43] Okay, any questions about the differences there and anything we've talked about in terms of type annotations and functions? So the question is, basically, is there some way to sort of maybe trick the rust compiler by saying this thing has the type object or maybe the type any and then that would allow you to reassign it on the fly from a float to a string or vice versa.
[00:04:05] Is that [INAUDIBLE] that cool? Yeah, so the short answer is no, you can't do that. So rust does not have an any type. It also doesn't have Java, you have object and everything inherits from object just about, it doesn't have either those. In fact, rust doesn't have inheritance in general.
[00:04:21] So basically, there really is no way to get around that. Now, it is possible to have Collections which contain multiple different types of their elements like you can have an array that contains simultaneously a string for some of its elements, and add a float for other elements, but the way that you do that is using something called EOMS which we'll get to and think two seconds from now.
[00:04:46] [LAUGH] So we haven't gotten there yet. But yeah, in general short answer is yeah, you can't do that [LAUGH].