From 744c3819a29a7c0a1407804de0c2c7980cd0f2c7 Mon Sep 17 00:00:00 2001 From: Mattrixwv Date: Thu, 11 Jun 2020 15:34:45 -0400 Subject: [PATCH] Added chapter 5 --- src/Types.rs | 4 ++++ src/Types/Aliasing.rs | 20 ++++++++++++++++ src/Types/Casting.rs | 52 ++++++++++++++++++++++++++++++++++++++++++ src/Types/Inference.rs | 15 ++++++++++++ src/Types/Literals.rs | 17 ++++++++++++++ src/main.rs | 21 +++++++++++++---- 6 files changed, 124 insertions(+), 5 deletions(-) create mode 100644 src/Types.rs create mode 100644 src/Types/Aliasing.rs create mode 100644 src/Types/Casting.rs create mode 100644 src/Types/Inference.rs create mode 100644 src/Types/Literals.rs diff --git a/src/Types.rs b/src/Types.rs new file mode 100644 index 0000000..b65c0d1 --- /dev/null +++ b/src/Types.rs @@ -0,0 +1,4 @@ +pub mod Casting; +pub mod Literals; +pub mod Inference; +pub mod Aliasing; diff --git a/src/Types/Aliasing.rs b/src/Types/Aliasing.rs new file mode 100644 index 0000000..c47379d --- /dev/null +++ b/src/Types/Aliasing.rs @@ -0,0 +1,20 @@ +//`NanoSecond` is a new name for `u64`. +type NanoSecond = u64; +type Inch = u64; + +//Use an attribute to silence warning. +#[allow(non_camel_case_types)] +type u64_t = u64; +//TODO ^ Try removing the attribute + +pub fn main(){ + //`NanoSecond` = `Inch` = `u64_t` = `u64`. + let nanoseconds: NanoSecond = 5 as u64_t; + let inches: Inch = 2 as u64_t; + + //Note that type aliases *don't* provide any extra type safety, because aliases are *not* new types + println!("{} nanoseconds + {} inches = {} unit?", + nanoseconds, + inches, + nanoseconds + inches); +} diff --git a/src/Types/Casting.rs b/src/Types/Casting.rs new file mode 100644 index 0000000..ab7f862 --- /dev/null +++ b/src/Types/Casting.rs @@ -0,0 +1,52 @@ +//Suppress all warnings from casts which overflow. +#![allow(overflowing_literals)] + +pub fn main(){ + let decimal = 65.4321_f32; + + //Error! No implicit conversion + //let integer: u8 = decimal; + //FIXME ^ Comment out this line + + //Explicit conversion + let integer = decimal as u8; + let character = integer as char; + + //Error! There are limitations in conversion rules. A float cannot be directly converted to a char. + //let character = decimal as char; + //FIXME ^ Comment out this line + + println!("Casting: {} -> {} -> {}", decimal, integer, character); + + //when casting any value to an unsigned type, T, + //T::MAX + 1 is added or subtracted until the value + //fits into the new type + + //1000 already fits in a u16 + println!("1000 as a u16 is: {}", 1000 as u16); + + //1000 - 256 - 256 - 256 = 232 + //Under the hood, the first 8 least significant bits (LSB) are kept, + //while the rest towards the most significant bit (MSB) get truncated. + println!("1000 as a u8 is : {}", 1000 as u8); + //-1 + 256 = 255 + println!(" -1 as a u8 is : {}", (-1i8) as u8); + + //For positive numbers, this is the same as the modulus + println!("1000 mod 256 is : {}", 1000 % 256); + + //When casting to a signed type, the (bitwise) result is the same as + //first casting to the corresponding unsigned type. If the most significant + //bit of that value is 1, then the value is negative. + + //Unless it already fits, of course. + println!(" 128 as a i16 is: {}", 128 as i16); + //128 as u8 -> 128, whose two's complement in eight bits is: + println!(" 128 as a i8 is : {}", 128 as i8); + + //repeating the example above + //1000 as u8 -> 232 + println!("1000 as a u8 is : {}", 1000 as u8); + //and the two's complement of 232 is -24 + println!(" 232 as a i8 is : {}", 232 as i8); +} diff --git a/src/Types/Inference.rs b/src/Types/Inference.rs new file mode 100644 index 0000000..6ecb2e0 --- /dev/null +++ b/src/Types/Inference.rs @@ -0,0 +1,15 @@ +pub fn main(){ + //Because of the annotation, the compiler knows that `elem` has type u8. + let elem = 5u8; + + //Create an empty vector (a growable array). + let mut vec = Vec::new(); + //At this point the compiler doesn't know the exact type of `vec`, it just knows that it's a vector of something (`Vec<_>`). + + //Insert `elem` in the vector. + vec.push(elem); + //Aha! Now the compiler knows that `vec` is a vector of `u8`s (`Vec`) + //TODO ^ Try commenting out the `vec.push(elem)` line + + println!("{:?}", vec); +} diff --git a/src/Types/Literals.rs b/src/Types/Literals.rs new file mode 100644 index 0000000..c73f20d --- /dev/null +++ b/src/Types/Literals.rs @@ -0,0 +1,17 @@ +pub fn main(){ + //Suffixed literals, their types are known at initialization + let x = 1u8; + let y = 2u32; + let z = 3f32; + + //Unsuffixed literal, their types depend on how they are used + let i = 1; + let f = 1.0; + + //`size_of_val` returns the size of a variable in bytes + println!("size of `x` in bytes: {}", std::mem::size_of_val(&x)); + println!("size of `y` in bytes: {}", std::mem::size_of_val(&y)); + println!("size of `z` in bytes: {}", std::mem::size_of_val(&z)); + println!("size of `i` in bytes: {}", std::mem::size_of_val(&i)); + println!("size of `f` in bytes: {}", std::mem::size_of_val(&f)); +} diff --git a/src/main.rs b/src/main.rs index b528f92..3d40b73 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ mod HelloWorld; mod Primitives; mod CustomTypes; mod VariableBindings; +mod Types; fn main(){ @@ -45,13 +46,23 @@ fn main(){ //CustomTypes::Constants::main(); //4 Variable Bindings - VariableBindings::main(); + //VariableBindings::main(); //4.1 Mutability - VariableBindings::Mutability::main(); + //VariableBindings::Mutability::main(); //4.2 Scope and Shadowing - VariableBindings::ScopeAndShadowing::main(); + //VariableBindings::ScopeAndShadowing::main(); //4.3 Declare First - VariableBindings::DeclareFirst::main(); + //VariableBindings::DeclareFirst::main(); //4.4 Freezing - VariableBindings::Freezing::main(); + //VariableBindings::Freezing::main(); + + //5 Types + //5.1 Casting + Types::Casting::main(); + //5.2 Literals + Types::Literals::main(); + //5.3 Inference + Types::Inference::main(); + //5.4 Aliasing + Types::Aliasing::main(); }