“If a person will spend one hour a day on the same subject for five years, that person will be an expert on that subject.”
__ Earl Nightingale
RUST : BEYOND THE BASICS
“A language that doesn’t affect the way you think about programming, is not worth knowing.”medium.com
▸ Installation & Hello World ▸ Cargo & Crates ▸ Variable bindings , Constants & Statics ▸ Comments ▸ Functions ▸ Primitive Data Types
▸ Operators ▸ Control Flows
Today we will go little bit deeper into Rust Programming Language. Let’s start from what we have missed last time.
If you remember, array is a fixed-size list of elements, of same data type. Even with
mut , it’s element count can not be changed. Vector is kind of a re-sizable array but all elements must be in the same type.
⭐️ It is a generic type, written as Vec<T> . T can have any type, ex. The type of a Vec of i32s is
Vec<i32> . Also Vectors always allocate their data in dynamically allocated heap.
⭐️ Mainly a vector represents 3 things; a pointer to the data, No of elements currently have(length), capacity (Amount of space allocated for any future elements). If the length of a vector exceeds its capacity, its capacity will be increased automatically. But its elements will be reallocated(which can be slow). So always use Vec::with_capacity whenever it’s possible.
🔎 String data type is a UTF-8 encoded vector. But you can not index into a String because of encoding.
💯 Vectors can be used with iterators in three ways,
⭐️ Structs are used to encapsulate related properties into one unified datatype.
💡 By convention, the name of the struct starts with a capital letter and follows CamelCase.
There are 3 variants of structs,
01. C-like structs
▸ one or more comma separated name:value pairs
▸ brace-enclosed list
▸ similar to classes (without it’s methods) in other languages like Java
▸ because fields have names, we can access them through dot notation
02. Tuple structs
▸ one or more comma separated values
▸ parenthesized list like tuples
▸ looks like a named tuples
03. Unit structs
▸ a struct with no members at all
▸ it defines a new type but it resembles an empty tuple, ()
▸ rarely in use, useful with generics
⭐️ When regarding OOP in Rust, attributes and methods are placed separately on structs and traits. Structs contain only attributes, traits contain only methods. They are getting connected via impls .
- C-like structs
- Tuple structs
⭐️ When a tuple struct has only one element, we call it a ‘newtype’ pattern. Because it helps to create a new type.
- Unit structs
This is rarely useful on its own, but in combination with other features, it can be useful.
⭐️ An enum is a single type. It contains variants, which are possible values of the enum at a given time. For example,
⭐️ Variants can be accessed through :: notation , ex. Day::Sunday
⭐️ Each enum variant can have,
▸ no data (unit variant)
▸ unnamed ordered data (tuple variant)
▸ named data (struct variant)
📖 Sometimes, when writing a function or data type, we may want it to work for multiple types of arguments. In Rust, we can do this with generics.
💭 The concept is, instead of declaring a specific data type we use an uppercase letter(or CamelCase identifier). ex, instead x : u8 we use x : T . But we have to inform to the compiler that T is a generic type(can be any type) by adding <T> at first.
⭐️ Above Option and Result types are kind of special generic types which are already defined in Rust’s standard library.
• An optional value can have either Some value or no value/ None.
• A result can represent either success/ Ok or failure/ Err
📖 The Option type is a way to use Rust’s type system to express the possibility of absence. Result expresses the possibility of error.
🔎 Many useful methods have been implemented around Option and Result types. More information can be found on std::option::Option and std::result::Result pages on Rust doc.
💡 Also more practical examples of options & results can be found on Error Handling section in Rust doc.
Impls & Traits
💡 When we discussed about C-like structs, I mentioned that those are similar to classes in other languages like Java, but without their methods. impls are used to define methods for Rust structs and enums.
💡 Traits are kind of similar to interfaces in other languages like Java. They are used to define the functionality a type must provide. Multiple traits can be implemented to a single type.
⭐️ But traits can also include default implementations of methods. Default methods can be overridden when implementing types.
⭐️ As you can see methods take a special first parameter, the type itself. It can be either self, &self, or &mut self . self if it’s a value on the stack(taking ownership), &self if it’s a reference, and &mut self if it’s a mutable reference.
⭐️ Some other languages support static methods. At such times, we call a function directly through the class without creating an object. In Rust, we call them Associated Functions. we use :: instead of . when calling them from struct. ex. Person::new(“Elon Musk Jr”);
⭐️ Traits may inherit from other traits.
While Rust favors static dispatch, it also supports dynamic dispatch through a mechanism called ‘trait objects.’
📖 Dynamic dispatch is the process of selecting which implementation of a polymorphic operation (method or function) to call at run time, while static dispatch is doing this at compile time.
▸ Vectors ▸ Structs ▸ Enums ▸ Generics ▸ Impls & Traits
🐣 As you might know, I am not an expert in Rust. I’m a Web Developer who is just learning Rust. Mostly I studied and wrote this at late nights, so this can have some mistakes. Please correct me if you found any kind of mistake, even in grammar, even in the previous post :) Thanks.
“Believe you can and you’re halfway there.”
— Theodore Roosevelt
NEXT ▸ Ownership▸ Borrowing▸ Lifetimes & Lifetime Elision