SlideShare a Scribd company logo
Introduction to Rust
Part II
Presented by -
Vanshika Srivastava & Sheshnath
Software Consultant
Lack of etiquette and manners is a huge turn off.
KnolX Etiquettes
 Punctuality
Join the session 5 minutes prior to the session start time. We start on
time and conclude on time!
 Feedback
Make sure to submit a constructive feedback for all sessions as it is very
helpful for the presenter.
 Silent Mode
Keep your mobile devices in silent mode, feel free to move out of session
in case you need to attend an urgent call.
 Avoid Disturbance
Avoid unwanted chit chat during the session.
1. Brief Overview
2. Pattern Matching in Rust
 Types of Patterns
3. Error Handling
4. Smart Pointers
 Tyes of Smart Pointers
5. Generics
 Types of Generics
6. Traits
Introduction To Rust part II Presentation
Brief Overview
 Rust is a modern systems programming language designed for safety, concurrency, and
performance.
 Its key features include strong static typing, zero-cost abstractions, and a focus on memory safety
without sacrificing performance.
 One of its most distinctive features is its ownership system, which ensures memory safety by
enforcing strict rules about how memory is accessed and manipulated.
 Ownership rules prevent common pitfalls like null pointer dereferencing, dangling pointers, and
data races by enforcing a single owner for each piece of data and allowing controlled borrowing
and lending of references.
 This approach enables efficient memory management and eliminates many common bugs at
compile time, making Rust a powerful choice for building reliable and efficient software systems.
 Pattern matching is a fundamental concept in Rust for handling control flow based on the
structure of data.
 Rust's match keyword allows for exhaustive and flexible pattern matching.
 Pattern matching in Rust is a powerful feature that allows developers to destructure complex data
types and control flow based on the structure of those types. It is primarily achieved through the
match keyword, which resembles the switch statement found in other languages but offers more
flexibility and safety.
Syntax:
match expression {
pattern1 => code_block1,
pattern2 => code_block2,
// More patterns...
_ => default_code_block // Optional default case
}
Pattern Matching in Rust
 expression: The value to match against.
 Pattern: Describes the structure to match against.
 => Separates pattern from associated code block.
 _ Wildcard pattern for unmatched cases.
 , Separates different patterns and code blocks.
Example -
 Matching Literals- Matches against specific constant values.
The following code gives some examples:
let x = 1;
match x {
1 => println!("one"),
2 => println!("two"),
3 => println!("three"),
_ => println!("anything"),
}
 This code prints one because the value in x is 1. This syntax is useful when you want your code
to take an action if it gets a particular concrete value.
Types of Patterns -
Multiple Patterns
 In match expressions, you can match multiple patterns using the | syntax, which is the
pattern or operator. For example, in the following code we match the value of x against the match
arms, the first of which has an or option, meaning if the value of x matches either of the values in
that arm, that arm’s code will run:
let x = 1;
match x {
1 | 2 => println!("one or two"),
3 => println!("three"),
_ => println!("anything"),
}
Matching Ranges of Values with ..=
 The ..= syntax allows us to match to an inclusive range of values. In the following code, when a
pattern matches any of the values within the given range, that arm will execute:
let x = 5;
match x {
1..=5 => println!("one through five"),
_ => println!("something else"),
}
 If x is 1, 2, 3, 4, or 5, the first arm will match. This syntax is more convenient for multiple match values than
using the | operator to express the same idea; if we were to use | we would have to specify 1 | 2 | 3 | 4 | 5.
Specifying a range is much shorter, especially if we want to match, say, any number between 1 and 1,000!
 The compiler checks that the range isn’t empty at compile time, and because the only types for which Rust
can tell if a range is empty or not are char and numeric values, ranges are only allowed with numeric
or char values.
 Here is an example using ranges of char values:
let x = 'c';
match x {
'a'..='j' => println!("early ASCII letter"),
'k'..='z' => println!("late ASCII letter"),
_ => println!("something else"),
}
Destructuring to Break Apart Values
struct Point { x: i32, y: i32, }
fn main() {
let p = Point { x: 0, y: 7 };
match p {
Point { x, y: 0 } => println!("On the x axis at {x}"),
Point { x: 0, y } => println!("On the y axis at {y}"),
Point { x, y } => {
println!("On neither axis: ({x}, {y})");
}
}
}
Remember that a match expression stops checking arms
once it has found the first matching pattern, so even
though Point { x: 0, y: 0} is on the x axis and the y axis, this
code would only print On the x axis at 0.
Destructuring Structs -
enum Message {
Quit,
Write(String),
ChangeColor(i32, i32, i32),
}
fn main() {
let msg = Message::ChangeColor(0, 160, 255);
match msg {
Message::Quit => {
println!("The Quit variant has no data ."); }
Message::Write(text) => {
println!("Text message: {text}"); }
Message::ChangeColor(r, g, b) => {
println!("Change the color to red {r}, green {g}, and blue {b}",)
}
}
}
Destructuring Enums -
Ignoring Values in a Pattern
 You’ve seen that it’s sometimes useful to ignore values in a pattern, such as in the last arm of a match, to get a
catchall that doesn’t actually do anything but does account for all remaining possible values.
Ignoring an Entire Value with _
 We’ve used the underscore as a wildcard pattern that will match any value but not bind to the value. This is
especially useful as the last arm in a match expression, but we can also use it in any pattern, including function
parameters.
fn foo(_: i32, y: i32) {
println!("This code only uses the y parameter: {}", y);
}
fn main() {
foo(3, 4);
}
 This code will completely ignore the value 3 passed as the first argument, and will print This code only uses the y
parameter: 4.
 Extra Conditionals with Match Guards
 A match guard is an additional if condition, specified after the pattern in a match arm, that must also match for
that arm to be chosen. Match guards are useful for expressing more complex ideas than a pattern alone
allows.
let num = Some(4);
match num {
Some(x) if x % 2 == 0 => println!("The number {} is even", x),
Some(x) => println!("The number {} is odd", x), None => (),
}
Benefits of Pattern Matching -
 Exhaustiveness: Encourages handling of all possible cases.
 Safety: Ensures exhaustive matching, reducing runtime errors.
 Expressiveness: Concise syntax for complex control flow.
Error Handling
 Rust favors handling errors explicitly rather than through exceptions.
 Exceptional cases are represented using Result and Option types.
 For unrecoverable errors, Rust provides the panic! macro.
 Sometimes, bad things happen in your code, and there’s nothing you can do about it. In these cases, Rust
has the panic! macro. There are two ways to cause a panic in practice: by taking an action that causes our
code to panic (such as accessing an array past the end) or by explicitly calling the panic! macro. In both
cases, we cause a panic in our program. By default, these panics will print a failure message, unwind, clean
up the stack, and quit.
 By default, when a panic occurs, the program starts unwinding, which means Rust walks back up the stack
and cleans up the data from each function it encounters. However, this walking back and cleanup is a lot of
work. Rust, therefore, allows you to choose the alternative of immediately aborting, which ends the program
without cleaning up. Memory that the program was using will then need to be cleaned up by the operating
system.
Result Type
 Most errors aren’t serious enough to require the
program to stop entirely. Sometimes, when a
function fails, it’ for a reason that you can easily
interpret and respond to. For example, if you try to
open a file and that operation fails because the file
doesn’t exist, you might want to create the file
instead of terminating the process.
 enum Result<T, E> {
Ok(T),
Err(E),
}
 T represents the type of the value that will be
returned in a success case within
the Ok variant, and E represents the type of the
error that will be returned in a failure case within
the Err variant.
Recoverable Errors with Result
fn divide(x: i32, y: i32) -> Result<i32, &'static str> {
if y == 0 {
return Err("Division by zero");
}
Ok(x / y)
}
fn main() {
let result = divide(10, 0);
match result {
Ok(value) => println!("Result: {}", value),
Err(error) => println!("Error: {}", error),
}
}
Handling Results -
Option Type
 Represents an optional value that may or may not exist.
enum Option<T> {
Some(T),
None,
}
Handling Options -
Panic Macro
 Used for unrecoverable errors or exceptional situations.
Unwinding vs. Aborting
 Rust allows two modes of handling panics: unwinding and aborting.
 Unwinding performs stack unwinding to clean up resources.
 Aborting terminates the program without unwinding the stack.
Benefits of Error Handling -
 Explicitness: Errors are handled explicitly using Result and Option.
 Safety: Encourages handling of error cases, reducing runtime failures.
 Predictability: No unexpected control flow due to exceptions.
Smart Pointers
 Smart pointers are specialized data structures in Rust's standard library that resemble traditional pointers but
offer enhanced functionalities and safety features.
 They provide automatic memory management, ensuring that memory is deallocated when the smart pointer
goes out of scope, thereby preventing memory leaks.
 They encapsulate raw pointers and manage the memory allocation and deallocation process internally,
reducing the risk of memory leaks and dangling pointers.
 Types of Smart Pointers :
o Box<T>
o Rc<T>
o Arc<T>
o Mutex<T> & RwLock<T>
Box <T>
o Box<T> is the simplest smart pointer in Rust. It allows you to allocate memory on the heap and store a
value there. When the Box goes out of scope, its destructor is called, and the memory is deallocated.
Use Cases:
o Storing data of unknown size at compile time.
o Creating recursive data structures.
o Moving data between different parts of your program.
Example :
Types of Smart Pointers
fn main() {
let b = Box::new(5); // b is a Box pointing to an integer on the heap
println!("Value inside the Box: {}", b);
}
Rc <T>
• Rc<T> : (Reference Counted) is a smart pointer for shared ownership. It keeps track of the number of
references to a value and automatically cleans up the data when the last reference is dropped.
 It allows multiple ownership of data within a single thread.
 Rc is lightweight and performs well for small data structures.
Use Cases
o Use Rc when you need shared ownership within a single thread.
Example : use std::rc::Rc;
fn main(){
let data = Rc::new(42);
let reference1 = Rc::clone(&data);
let reference2 = Rc::clone(&data);
println!("Data: {}", data);
}
Arc<T>
 Arc<T> (Atomically Reference Counted) is similar to Rc<T> but is thread-safe and can be shared
across threads. It uses atomic operations to manipulate the reference count, ensuring thread
safety.
 Use Cases:
o Sharing immutable data between multiple threads.
 Example :
use std::sync::Arc;
use std::thread;
fn main() {
let data = Arc::new(42);
let data_clone = Arc::clone(&data);
let handle = thread::spawn(move || {
println!("Data in thread: {}", data_clone);
});
handle.join().unwrap();
println!("Data in main thread: {}", data);
}
Mutex<T> and RwLock<T>:
 Mutex<T> and RwLock<T> are smart pointers that provide interior mutability by synchronizing access to
shared data. Mutex<T> allows only one thread to access the data at a time, while RwLock<T> allows
multiple readers or one writer at a time
 Use Cases:
Sharing mutable data between multiple threads safely.
 Example :
Generics <T>
 Generics in Rust are a powerful language feature that allows you to write code that operates on different
types while maintaining type safety.
 They provide a way to write reusable code that can work with different types and across multiple context
without sacrificing performance or safety
 Let's explore generics and their uses in different aspects of Rust programming:
o Functions
o Structs
o Enums
o Methods
Functions<T>
 Functions : In functions, generics allow you to write code that can accept arguments of any type. Instead
of specifying concrete types, you use placeholder type parameters.
 Example :
 Use Cases : Generics in functions are handy when you want to create a function that can operate on
different types without having to duplicate code for each type.
fn print_value<T>(value: T) {
println!("Value: {}", value);
}
Structs<T>
 Generics in structs allow you to define data structures that can hold values of any type. Similar to functions,
you use placeholder type parameters when defining a generic struct.
 Example :
 Use cases : Generic structs are useful when you need to create a data structure that can store elements of
various types in a type-safe manner.
struct Pair<T> {
first: T,
second: T,
}
Enums<T>
 Enums with generics enable you to define variants that can hold values of different types. Like structs, you
use placeholder type parameters for generic enum variants.
 Example :
 Use cases :Generic enums are often used to represent results or errors that can contain values of different
types, providing flexibility and type safety.
enum Result {
Ok(T),
Err(E),
}
Methods <T>
 Rust allows you to define generic methods on structs. You use the same syntax with type parameters as in
functions and structs.
 Example :
 Use cases : Generic methods enable you to define behaviour that can work with any type, providing code
reuse and flexibility.
impl<T> Pair<T> {
fn get_first(&self) -> &T {
&self.first
}
}
Performance of Generics
 Generics in Rust are a zero-cost abstraction. The compiler generates specialized versions of generic code for
each concrete type it's used with, eliminating runtime overhead.
 Rust's monomorphization process ensures that generic code is compiled into efficient and specialized
versions, resulting in performance similar to non-generic code.
 Overall, generics in Rust are a fundamental feature that enables code abstraction, reuse, and type safety
across various aspects of Rust programming, including functions, structs, enums, methods, and more. They
contribute to writing clear, concise, and efficient code in Rust.
Traits
 Traits define behavior that types can implement.
 They specify a set of methods that types must provide to satisfy the trait's requirements.
 Methods within a trait are like function signatures, outlining what actions a type should support.
 Traits act as contracts or interfaces in Rust, setting rules that types must follow to be considered part of a
group or to have a certain capability.
 Once a type implements a trait, it gains access to the behaviors defined by that trait.
 This allows different types to share common behavior, making them interchangeable in code that relies on
traits.
 Traits promote code reuse and polymorphism, enabling more flexible and versatile Rust code.
Types of Traits
 Marker Trait : Traits that do not contain any method signatures and are used to provide type-level
information or as flags.
 Trait with Associated Functions: Traits that contain associated functions (functions associated with the trait
itself).
 Trait with Required Methods: Traits that define a set of methods that types must implement.
 Trait with Default Implementations: Traits that provide default implementations for some or all of their
methods, allowing types to choose whether to override them.
 Trait with Supertraits: Traits that inherit methods from other traits, enabling hierarchical trait composition.
Demo
QnA
Introduction To Rust part II Presentation

More Related Content

PPTX
Introduction to Rust (Presentation).pptx
PPTX
Rust Intro
PDF
Rust All Hands Winter 2011
PPTX
MozillaPH Rust Hack & Learn Session 2
PDF
Rust for professionals.pdf
PPTX
Rust presentation convergeconf
PDF
Short intro to the Rust language
PDF
Rust in Action Systems programming concepts and techniques 1st Edition Tim Mc...
Introduction to Rust (Presentation).pptx
Rust Intro
Rust All Hands Winter 2011
MozillaPH Rust Hack & Learn Session 2
Rust for professionals.pdf
Rust presentation convergeconf
Short intro to the Rust language
Rust in Action Systems programming concepts and techniques 1st Edition Tim Mc...

Similar to Introduction To Rust part II Presentation (20)

PDF
Reason - introduction to language and its ecosystem | Łukasz Strączyński
PDF
Who go Types in my Systems Programing!
PDF
Intro to Rust 2019
PDF
Le langage rust
PDF
RUSTing -- Partially Ordered Rust Programming Ruminations
PDF
Rust - Fernando Borretti
PDF
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...
PDF
Redox OS
PPTX
Why Is Rust Gaining Traction In Recent Years?
PDF
Deep drive into rust programming language
PDF
The Rust Programming Language: an Overview
PDF
Rust With async / .await
PDF
Introduction to the rust programming language
PPTX
A Slice Of Rust - A quick look at the Rust programming language
PPTX
Introduction to Rust language programming
PDF
The Rust Programming Language 2nd Edition Second Converted Steve Klabnik Caro...
PDF
Rust Intro @ Roma Rust meetup
PDF
Rustlabs Quick Start
PPTX
First Ride on Rust
Reason - introduction to language and its ecosystem | Łukasz Strączyński
Who go Types in my Systems Programing!
Intro to Rust 2019
Le langage rust
RUSTing -- Partially Ordered Rust Programming Ruminations
Rust - Fernando Borretti
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...
Redox OS
Why Is Rust Gaining Traction In Recent Years?
Deep drive into rust programming language
The Rust Programming Language: an Overview
Rust With async / .await
Introduction to the rust programming language
A Slice Of Rust - A quick look at the Rust programming language
Introduction to Rust language programming
The Rust Programming Language 2nd Edition Second Converted Steve Klabnik Caro...
Rust Intro @ Roma Rust meetup
Rustlabs Quick Start
First Ride on Rust
Ad

More from Knoldus Inc. (20)

PPTX
Angular Hydration Presentation (FrontEnd)
PPTX
Optimizing Test Execution: Heuristic Algorithm for Self-Healing
PPTX
Self-Healing Test Automation Framework - Healenium
PPTX
Kanban Metrics Presentation (Project Management)
PPTX
Java 17 features and implementation.pptx
PPTX
Chaos Mesh Introducing Chaos in Kubernetes
PPTX
GraalVM - A Step Ahead of JVM Presentation
PPTX
Nomad by HashiCorp Presentation (DevOps)
PPTX
Nomad by HashiCorp Presentation (DevOps)
PPTX
DAPR - Distributed Application Runtime Presentation
PPTX
Introduction to Azure Virtual WAN Presentation
PPTX
Introduction to Argo Rollouts Presentation
PPTX
Intro to Azure Container App Presentation
PPTX
Insights Unveiled Test Reporting and Observability Excellence
PPTX
Introduction to Splunk Presentation (DevOps)
PPTX
Code Camp - Data Profiling and Quality Analysis Framework
PPTX
AWS: Messaging Services in AWS Presentation
PPTX
Amazon Cognito: A Primer on Authentication and Authorization
PPTX
ZIO Http A Functional Approach to Scalable and Type-Safe Web Development
PPTX
Managing State & HTTP Requests In Ionic.
Angular Hydration Presentation (FrontEnd)
Optimizing Test Execution: Heuristic Algorithm for Self-Healing
Self-Healing Test Automation Framework - Healenium
Kanban Metrics Presentation (Project Management)
Java 17 features and implementation.pptx
Chaos Mesh Introducing Chaos in Kubernetes
GraalVM - A Step Ahead of JVM Presentation
Nomad by HashiCorp Presentation (DevOps)
Nomad by HashiCorp Presentation (DevOps)
DAPR - Distributed Application Runtime Presentation
Introduction to Azure Virtual WAN Presentation
Introduction to Argo Rollouts Presentation
Intro to Azure Container App Presentation
Insights Unveiled Test Reporting and Observability Excellence
Introduction to Splunk Presentation (DevOps)
Code Camp - Data Profiling and Quality Analysis Framework
AWS: Messaging Services in AWS Presentation
Amazon Cognito: A Primer on Authentication and Authorization
ZIO Http A Functional Approach to Scalable and Type-Safe Web Development
Managing State & HTTP Requests In Ionic.
Ad

Recently uploaded (20)

PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Machine learning based COVID-19 study performance prediction
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Electronic commerce courselecture one. Pdf
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PPTX
Programs and apps: productivity, graphics, security and other tools
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Review of recent advances in non-invasive hemoglobin estimation
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
KodekX | Application Modernization Development
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
Approach and Philosophy of On baking technology
PPTX
MYSQL Presentation for SQL database connectivity
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Machine learning based COVID-19 study performance prediction
The Rise and Fall of 3GPP – Time for a Sabbatical?
Mobile App Security Testing_ A Comprehensive Guide.pdf
Electronic commerce courselecture one. Pdf
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Programs and apps: productivity, graphics, security and other tools
Digital-Transformation-Roadmap-for-Companies.pptx
Diabetes mellitus diagnosis method based random forest with bat algorithm
Review of recent advances in non-invasive hemoglobin estimation
Understanding_Digital_Forensics_Presentation.pptx
Per capita expenditure prediction using model stacking based on satellite ima...
NewMind AI Weekly Chronicles - August'25 Week I
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
KodekX | Application Modernization Development
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Approach and Philosophy of On baking technology
MYSQL Presentation for SQL database connectivity

Introduction To Rust part II Presentation

  • 1. Introduction to Rust Part II Presented by - Vanshika Srivastava & Sheshnath Software Consultant
  • 2. Lack of etiquette and manners is a huge turn off. KnolX Etiquettes  Punctuality Join the session 5 minutes prior to the session start time. We start on time and conclude on time!  Feedback Make sure to submit a constructive feedback for all sessions as it is very helpful for the presenter.  Silent Mode Keep your mobile devices in silent mode, feel free to move out of session in case you need to attend an urgent call.  Avoid Disturbance Avoid unwanted chit chat during the session.
  • 3. 1. Brief Overview 2. Pattern Matching in Rust  Types of Patterns 3. Error Handling 4. Smart Pointers  Tyes of Smart Pointers 5. Generics  Types of Generics 6. Traits
  • 5. Brief Overview  Rust is a modern systems programming language designed for safety, concurrency, and performance.  Its key features include strong static typing, zero-cost abstractions, and a focus on memory safety without sacrificing performance.  One of its most distinctive features is its ownership system, which ensures memory safety by enforcing strict rules about how memory is accessed and manipulated.  Ownership rules prevent common pitfalls like null pointer dereferencing, dangling pointers, and data races by enforcing a single owner for each piece of data and allowing controlled borrowing and lending of references.  This approach enables efficient memory management and eliminates many common bugs at compile time, making Rust a powerful choice for building reliable and efficient software systems.
  • 6.  Pattern matching is a fundamental concept in Rust for handling control flow based on the structure of data.  Rust's match keyword allows for exhaustive and flexible pattern matching.  Pattern matching in Rust is a powerful feature that allows developers to destructure complex data types and control flow based on the structure of those types. It is primarily achieved through the match keyword, which resembles the switch statement found in other languages but offers more flexibility and safety. Syntax: match expression { pattern1 => code_block1, pattern2 => code_block2, // More patterns... _ => default_code_block // Optional default case } Pattern Matching in Rust
  • 7.  expression: The value to match against.  Pattern: Describes the structure to match against.  => Separates pattern from associated code block.  _ Wildcard pattern for unmatched cases.  , Separates different patterns and code blocks. Example -
  • 8.  Matching Literals- Matches against specific constant values. The following code gives some examples: let x = 1; match x { 1 => println!("one"), 2 => println!("two"), 3 => println!("three"), _ => println!("anything"), }  This code prints one because the value in x is 1. This syntax is useful when you want your code to take an action if it gets a particular concrete value. Types of Patterns -
  • 9. Multiple Patterns  In match expressions, you can match multiple patterns using the | syntax, which is the pattern or operator. For example, in the following code we match the value of x against the match arms, the first of which has an or option, meaning if the value of x matches either of the values in that arm, that arm’s code will run: let x = 1; match x { 1 | 2 => println!("one or two"), 3 => println!("three"), _ => println!("anything"), } Matching Ranges of Values with ..=  The ..= syntax allows us to match to an inclusive range of values. In the following code, when a pattern matches any of the values within the given range, that arm will execute:
  • 10. let x = 5; match x { 1..=5 => println!("one through five"), _ => println!("something else"), }  If x is 1, 2, 3, 4, or 5, the first arm will match. This syntax is more convenient for multiple match values than using the | operator to express the same idea; if we were to use | we would have to specify 1 | 2 | 3 | 4 | 5. Specifying a range is much shorter, especially if we want to match, say, any number between 1 and 1,000!  The compiler checks that the range isn’t empty at compile time, and because the only types for which Rust can tell if a range is empty or not are char and numeric values, ranges are only allowed with numeric or char values.  Here is an example using ranges of char values: let x = 'c'; match x { 'a'..='j' => println!("early ASCII letter"), 'k'..='z' => println!("late ASCII letter"), _ => println!("something else"), }
  • 11. Destructuring to Break Apart Values struct Point { x: i32, y: i32, } fn main() { let p = Point { x: 0, y: 7 }; match p { Point { x, y: 0 } => println!("On the x axis at {x}"), Point { x: 0, y } => println!("On the y axis at {y}"), Point { x, y } => { println!("On neither axis: ({x}, {y})"); } } } Remember that a match expression stops checking arms once it has found the first matching pattern, so even though Point { x: 0, y: 0} is on the x axis and the y axis, this code would only print On the x axis at 0. Destructuring Structs - enum Message { Quit, Write(String), ChangeColor(i32, i32, i32), } fn main() { let msg = Message::ChangeColor(0, 160, 255); match msg { Message::Quit => { println!("The Quit variant has no data ."); } Message::Write(text) => { println!("Text message: {text}"); } Message::ChangeColor(r, g, b) => { println!("Change the color to red {r}, green {g}, and blue {b}",) } } } Destructuring Enums -
  • 12. Ignoring Values in a Pattern  You’ve seen that it’s sometimes useful to ignore values in a pattern, such as in the last arm of a match, to get a catchall that doesn’t actually do anything but does account for all remaining possible values. Ignoring an Entire Value with _  We’ve used the underscore as a wildcard pattern that will match any value but not bind to the value. This is especially useful as the last arm in a match expression, but we can also use it in any pattern, including function parameters. fn foo(_: i32, y: i32) { println!("This code only uses the y parameter: {}", y); } fn main() { foo(3, 4); }  This code will completely ignore the value 3 passed as the first argument, and will print This code only uses the y parameter: 4.
  • 13.  Extra Conditionals with Match Guards  A match guard is an additional if condition, specified after the pattern in a match arm, that must also match for that arm to be chosen. Match guards are useful for expressing more complex ideas than a pattern alone allows. let num = Some(4); match num { Some(x) if x % 2 == 0 => println!("The number {} is even", x), Some(x) => println!("The number {} is odd", x), None => (), } Benefits of Pattern Matching -  Exhaustiveness: Encourages handling of all possible cases.  Safety: Ensures exhaustive matching, reducing runtime errors.  Expressiveness: Concise syntax for complex control flow.
  • 14. Error Handling  Rust favors handling errors explicitly rather than through exceptions.  Exceptional cases are represented using Result and Option types.  For unrecoverable errors, Rust provides the panic! macro.  Sometimes, bad things happen in your code, and there’s nothing you can do about it. In these cases, Rust has the panic! macro. There are two ways to cause a panic in practice: by taking an action that causes our code to panic (such as accessing an array past the end) or by explicitly calling the panic! macro. In both cases, we cause a panic in our program. By default, these panics will print a failure message, unwind, clean up the stack, and quit.  By default, when a panic occurs, the program starts unwinding, which means Rust walks back up the stack and cleans up the data from each function it encounters. However, this walking back and cleanup is a lot of work. Rust, therefore, allows you to choose the alternative of immediately aborting, which ends the program without cleaning up. Memory that the program was using will then need to be cleaned up by the operating system.
  • 15. Result Type  Most errors aren’t serious enough to require the program to stop entirely. Sometimes, when a function fails, it’ for a reason that you can easily interpret and respond to. For example, if you try to open a file and that operation fails because the file doesn’t exist, you might want to create the file instead of terminating the process.  enum Result<T, E> { Ok(T), Err(E), }  T represents the type of the value that will be returned in a success case within the Ok variant, and E represents the type of the error that will be returned in a failure case within the Err variant. Recoverable Errors with Result fn divide(x: i32, y: i32) -> Result<i32, &'static str> { if y == 0 { return Err("Division by zero"); } Ok(x / y) } fn main() { let result = divide(10, 0); match result { Ok(value) => println!("Result: {}", value), Err(error) => println!("Error: {}", error), } } Handling Results -
  • 16. Option Type  Represents an optional value that may or may not exist. enum Option<T> { Some(T), None, } Handling Options -
  • 17. Panic Macro  Used for unrecoverable errors or exceptional situations.
  • 18. Unwinding vs. Aborting  Rust allows two modes of handling panics: unwinding and aborting.  Unwinding performs stack unwinding to clean up resources.  Aborting terminates the program without unwinding the stack. Benefits of Error Handling -  Explicitness: Errors are handled explicitly using Result and Option.  Safety: Encourages handling of error cases, reducing runtime failures.  Predictability: No unexpected control flow due to exceptions.
  • 19. Smart Pointers  Smart pointers are specialized data structures in Rust's standard library that resemble traditional pointers but offer enhanced functionalities and safety features.  They provide automatic memory management, ensuring that memory is deallocated when the smart pointer goes out of scope, thereby preventing memory leaks.  They encapsulate raw pointers and manage the memory allocation and deallocation process internally, reducing the risk of memory leaks and dangling pointers.  Types of Smart Pointers : o Box<T> o Rc<T> o Arc<T> o Mutex<T> & RwLock<T>
  • 20. Box <T> o Box<T> is the simplest smart pointer in Rust. It allows you to allocate memory on the heap and store a value there. When the Box goes out of scope, its destructor is called, and the memory is deallocated. Use Cases: o Storing data of unknown size at compile time. o Creating recursive data structures. o Moving data between different parts of your program. Example : Types of Smart Pointers fn main() { let b = Box::new(5); // b is a Box pointing to an integer on the heap println!("Value inside the Box: {}", b); }
  • 21. Rc <T> • Rc<T> : (Reference Counted) is a smart pointer for shared ownership. It keeps track of the number of references to a value and automatically cleans up the data when the last reference is dropped.  It allows multiple ownership of data within a single thread.  Rc is lightweight and performs well for small data structures. Use Cases o Use Rc when you need shared ownership within a single thread. Example : use std::rc::Rc; fn main(){ let data = Rc::new(42); let reference1 = Rc::clone(&data); let reference2 = Rc::clone(&data); println!("Data: {}", data); }
  • 22. Arc<T>  Arc<T> (Atomically Reference Counted) is similar to Rc<T> but is thread-safe and can be shared across threads. It uses atomic operations to manipulate the reference count, ensuring thread safety.  Use Cases: o Sharing immutable data between multiple threads.  Example : use std::sync::Arc; use std::thread; fn main() { let data = Arc::new(42); let data_clone = Arc::clone(&data); let handle = thread::spawn(move || { println!("Data in thread: {}", data_clone); }); handle.join().unwrap(); println!("Data in main thread: {}", data); }
  • 23. Mutex<T> and RwLock<T>:  Mutex<T> and RwLock<T> are smart pointers that provide interior mutability by synchronizing access to shared data. Mutex<T> allows only one thread to access the data at a time, while RwLock<T> allows multiple readers or one writer at a time  Use Cases: Sharing mutable data between multiple threads safely.  Example :
  • 24. Generics <T>  Generics in Rust are a powerful language feature that allows you to write code that operates on different types while maintaining type safety.  They provide a way to write reusable code that can work with different types and across multiple context without sacrificing performance or safety  Let's explore generics and their uses in different aspects of Rust programming: o Functions o Structs o Enums o Methods
  • 25. Functions<T>  Functions : In functions, generics allow you to write code that can accept arguments of any type. Instead of specifying concrete types, you use placeholder type parameters.  Example :  Use Cases : Generics in functions are handy when you want to create a function that can operate on different types without having to duplicate code for each type. fn print_value<T>(value: T) { println!("Value: {}", value); }
  • 26. Structs<T>  Generics in structs allow you to define data structures that can hold values of any type. Similar to functions, you use placeholder type parameters when defining a generic struct.  Example :  Use cases : Generic structs are useful when you need to create a data structure that can store elements of various types in a type-safe manner. struct Pair<T> { first: T, second: T, }
  • 27. Enums<T>  Enums with generics enable you to define variants that can hold values of different types. Like structs, you use placeholder type parameters for generic enum variants.  Example :  Use cases :Generic enums are often used to represent results or errors that can contain values of different types, providing flexibility and type safety. enum Result { Ok(T), Err(E), }
  • 28. Methods <T>  Rust allows you to define generic methods on structs. You use the same syntax with type parameters as in functions and structs.  Example :  Use cases : Generic methods enable you to define behaviour that can work with any type, providing code reuse and flexibility. impl<T> Pair<T> { fn get_first(&self) -> &T { &self.first } }
  • 29. Performance of Generics  Generics in Rust are a zero-cost abstraction. The compiler generates specialized versions of generic code for each concrete type it's used with, eliminating runtime overhead.  Rust's monomorphization process ensures that generic code is compiled into efficient and specialized versions, resulting in performance similar to non-generic code.  Overall, generics in Rust are a fundamental feature that enables code abstraction, reuse, and type safety across various aspects of Rust programming, including functions, structs, enums, methods, and more. They contribute to writing clear, concise, and efficient code in Rust.
  • 30. Traits  Traits define behavior that types can implement.  They specify a set of methods that types must provide to satisfy the trait's requirements.  Methods within a trait are like function signatures, outlining what actions a type should support.  Traits act as contracts or interfaces in Rust, setting rules that types must follow to be considered part of a group or to have a certain capability.  Once a type implements a trait, it gains access to the behaviors defined by that trait.  This allows different types to share common behavior, making them interchangeable in code that relies on traits.  Traits promote code reuse and polymorphism, enabling more flexible and versatile Rust code.
  • 31. Types of Traits  Marker Trait : Traits that do not contain any method signatures and are used to provide type-level information or as flags.  Trait with Associated Functions: Traits that contain associated functions (functions associated with the trait itself).  Trait with Required Methods: Traits that define a set of methods that types must implement.  Trait with Default Implementations: Traits that provide default implementations for some or all of their methods, allowing types to choose whether to override them.  Trait with Supertraits: Traits that inherit methods from other traits, enabling hierarchical trait composition.
  • 32. Demo
  • 33. QnA