[Rust] Play around with Rust

Posted Answer1215

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Rust] Play around with Rust相关的知识,希望对你有一定的参考价值。

Few intertesting things from Rust

  • Option<T>: with Some, unwrap() function
  • todo(): to skil compiler error for a while
  • unreachable(): similar to Typescript, asserts never.
  • vec vs array
  • String vs &str
  • Struct, Impl
  • traits

 

Option<T>, similar to Maybe, Either

In Rust, Option is an enum that represents the possibility of a value being present (Some) or absent (None). The unwrap() method is used to extract the value from a Some variant or panic if the Option is None

fn main() 
    let maybe_number: Option<i32> = get_number();

    // Using unwrap() to get the value from the Option
    let number = maybe_number.unwrap();

    println!("The number is: ", number);


fn get_number() -> Option<i32> 
    // Return Some(value) if you have a value to return
    Some(42)

    // Return None if there is no value to return
    // None

Keep in mind that using unwrap() can be risky since it will cause your program to panic if the Option contains None.

It\'s generally better to use pattern matching or methods like unwrap_or, unwrap_or_default, or map to handle Option in a more graceful way.

 

unwrap_or: set default value if is None

fn main() 
    let maybe_number: Option<i32> = get_number();
    
    // Using unwrap_or() to get the value from the Option or use a default value
    let number = maybe_number.unwrap_or(0);

    println!("The number is: ", number);


fn get_number() -> Option<i32> 
    // Return Some(value) if you have a value to return
    // Some(42)

    // Return None if there is no value to return
    None

 

unwrap_or_default: set a defualt value by impl#[derive(Debug)]

#[derive()] is an attribute used to automatically generate certain trait implementations for a struct or enum. In the example provided, #[derive(Debug, Default)] is used to automatically generate the implementations for the Debug and Default traits for the Person struct

#[derive(Debug)]
struct Person 
    name: String,
    age: u32,


impl Default for Person 
    fn default() -> Self 
        Person 
            name: String::from("John Doe"),
            age: 18,
        
    



fn main() 
    let maybe_person: Option<Person> = get_person();
    
    // Using unwrap_or() to get the value from the Option or use a default value
    let person = maybe_person.unwrap_or_default();

    println!("The person is: :?", person); // The person is: Person  name: "John Doe", age: 18 


fn get_person() -> Option<Person> 
    None

 

todo & unreachable

fn only_evens(x: usize) -> bool 
    if x % 2 == 1 
        unreachable!("this should never happen")
    
    
    // without todo: `if` may be missing an `else` clause
    todo!("TODO: come to this part later")


fn main() 
  only_evens(10)

 

vec vs array

In Rust, arrays have a fixed size, so you can\'t change the size directly. However, you can use a Vec (vector) instead to achieve a similar effect. 

fn main() 
    let foo = vec![1, 2, 3];
    let foo = someMethod(foo);


fn someMethod(mut input: Vec<i32>) -> Vec<i32> 
    // Modify the input vector as needed
    input.push(4); // Adding 4 to the vector as an example
    input

need to use mut, otherwise, you cannot call .push().

 

String vs &str

String is a mutable, heap-allocated string type that owns its memory, while &str is an immutable reference to a string that doesn\'t own the memory it points to. Use String when you need to modify or build a string dynamically, and use &str when you need to pass a read-only reference to a string, such as in function parameters.

Creating string:

fn main() 
    let s1 = String::from("Hello, world!"); // Creates a String
    let s2: &str = "Hello, world!"; // Creates a string slice

    println!("s1: ", s1);
    println!("s2: ", s2);

 

Passing a `&str` to a function:

fn main() 
    let name = String::from("Alice");
    greet(&name); // Passing a string slice to the greet function


fn greet(name: &str) 
    println!("Hello, !", name);

 

Modify a String:

fn main() 
    let mut s = String::from("Hello");
    s.push_str(", world!");
    
    println!("s: ", s);

 

Creating a string slice from a `String`

fn main() 
    let s = String::from("Hello, world!");
    let hello = &s[0..5]; // Creating a string slice from a String

    println!("hello: ", hello);

 

Trait, Impl, Struct

  • Traits in Rust are used to define shared behavior across types. They can define methods, associated functions, and associated types.
  • Rust uses nominal typing, so a type must explicitly implement a trait using the impl Trait for Type syntax.
  • Traits are similar to interfaces in other languages, but they also allow you to provide default method implementations.
trait Person 
    fn name(&self) -> &str;
    fn age(&self) -> u32;
    
    fn greet(&self) 
        println!("Hello, my name is  and I \'m  years old", self.name(), self.age());
    


struct Student 
    name: String,
    age: u32,


impl Person for Student 
    fn name(&self) -> &str 
        &self.name
    
    
    fn age(&self) -> u32 
        self.age
    


fn main() 
    let student = Student  name: String::from("Alice"), age: 20 ;
    student.greet();

In the provided example, name is of type String, which is a growable, heap-allocated string type. When you return a reference to the name field using &self.name, you are borrowing a reference to the String without transferring ownership. This allows the name field to remain owned by the original Student struct while still providing read access to its content. The return type of the name method is &str, an immutable string slice, so returning a reference to a String as &str is appropriate.

On the other hand, age is of type u32, which is a simple, fixed-size, and copyable integer type. When you return self.age, you are returning a copy of the age field because u32 implements the Copy trait. This means that returning self.age does not affect the ownership or borrowing of the age field. The return type of the age method is u32, which matches the type of the age field, so returning self.age directly is appropriate.

In summary, you use &self.name to return a reference to the String as an immutable string slice (&str), and you use self.age to return a copy of the u32 value.

Array types are now written with the brackets around the element type问题的解决方法

在xcode6.1中来编写swift空数组时。出现的的这个问题,依照官方 Swift 教程《The Swift Programming Language》来写
let emptyArray = String[]() 时会提示“Array types are now written with the brackets around the element type”错误,正确的写法应该是

let emptyArray = [String]() 其他类型类似来处理就可以

以上是关于[Rust] Play around with Rust的主要内容,如果未能解决你的问题,请参考以下文章

bzoj4355 Play with sequence(吉司机线段树)题解

HDU 3487:Play with Chain(Splay)

Array types are now written with the brackets around the element type问题的解决方法

Sign around us. With more rules existing,signs are becoming common to everybody. It is easy for

Play-Morphia with Play 1.4

R语言ggplot2可视化删除图例(legend)周围的灰色矩形(remove the gray rectangle around the legend)