Skip to content

Instantly share code, notes, and snippets.

@nicolasdanelon
Created January 2, 2023 19:36
Show Gist options
  • Save nicolasdanelon/d47205cafc7660a4c4b4784614f6d581 to your computer and use it in GitHub Desktop.
Save nicolasdanelon/d47205cafc7660a4c4b4784614f6d581 to your computer and use it in GitHub Desktop.
understanding rust concepts
// Borrowing allows you to reference data without taking
// ownership of it. This can be useful when you have a large data
// structure and you don't want to copy it, or when you want to
// allow multiple parts of your code to access the same data.
fn main() {
let s1 = String::from("hello");
let len = calculate_length(&s1); // s1 is borrowed by the function
println!("The length of '{}' is {}.", s1, len);
}
fn calculate_length(s: &String) -> usize {
// s is a borrowed reference to a String
s.len()
}
// The function calculate_length borrows a
// reference to the variable s1 rather than taking ownership of it.
// This allows s1 to continue to be used in the println!
// statement after the call to calculate_length.
#[derive(Debug)]
enum Color {
Red,
Green,
Blue,
}
fn main() {
let c: Color = Color::Red;
match c {
Color::Red => println!("The color is red"),
Color::Green => println!("The color is green"),
Color::Blue => println!("The color is blue"),
}
}
// The lifetime of a value is the scope in which it is valid.
// Lifetimes are used to ensure that borrowed references are always valid.
fn main() {
let s1 = String::from("hello");
let s2 = String::from("world");
let result = longest(&s1, &s2);
println!("The longest string is {}", result);
}
fn longest<'a>(s1: &'a String, s2: &'a String) -> &'a String {
if s1.len() > s2.len() {
s1
} else {
s2
}
}
// The function longest takes two references
// to strings as arguments and returns a reference to the longer
// of the two strings. The lifetime parameter 'a is introduced to
// indicate that the returned reference has the same lifetime as
// the shorter of the two input references. This ensures that
// the returned reference is always valid.
// Ownership is a system that ensures that every value has a
// single owner and that the value is automatically dropped
// when its owner goes out of scope.
fn main() {
let s = String::from("hello"); // s is a new String with the value "hello"
take_ownership(s); // s is moved into the function and is no longer valid here
//println!("{}", s); // this line would cause a compile-time error
}
fn take_ownership(s: String) {
// s is now owned by this function
println!("{}", s);
}
// The variable s is created and initialized with the value "hello".
// The function take_ownership is then called with s as an argument. This causes the
// ownership of s to be transferred to the function. As a result, s is no longer
// valid after the call to take_ownership and attempting to use it will cause
// a compile-time error.
// A trait is a language feature that lets you define a set of
// behaviors that can be shared across multiple types. A type
// that implements a trait is said to be "compatible" with the trait.
trait Printable {
fn print(&self);
}
struct Point {
x: i32,
y: i32,
}
impl Printable for Point {
fn print(&self) {
println!("({}, {})", self.x, self.y);
}
}
fn main() {
let p = Point { x: 3, y: 4 };
p.print(); // prints "(3, 4)"
}
// We define a trait called Printable with a single method, print.
// We then define a struct called Point with two fields, x and y.
// We use the impl keyword to implement the Printable trait for the Point struct.
// This means that any value of type Point now has a print method that can be called.
// In the main function, we create a value of type Point and call its print method.
// This will print the string "(3, 4)".
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment