Der Option-Typ bedeutet, dass der Wert vom Typ Some (es gibt etwas) oder None sein könnte:
pubenumOption<T> {None,Some(T),}
Sie können Funktionen wie is_some() oder is_none() verwenden, um den Wert der Option zu überprüfen.
Makros
Makros sind mächtiger als Funktionen, da sie sich erweitern, um mehr Code zu erzeugen, als den Code, den Sie manuell geschrieben haben. Zum Beispiel muss eine Funktionssignatur die Anzahl und den Typ der Parameter deklarieren, die die Funktion hat. Makros hingegen können eine variable Anzahl von Parametern annehmen: Wir können println!("hello") mit einem Argument oder println!("hello {}", name) mit zwei Argumenten aufrufen. Außerdem werden Makros erweitert, bevor der Compiler die Bedeutung des Codes interpretiert, sodass ein Makro beispielsweise ein Trait für einen bestimmten Typ implementieren kann. Eine Funktion kann das nicht, da sie zur Laufzeit aufgerufen wird und ein Trait zur Compile-Zeit implementiert werden muss.
macro_rules!my_macro {() => {println!("Check out my macro!");};($val:expr) => {println!("Look at this other macro: {}", $val);}}fnmain() {my_macro!();my_macro!(7777);}// Export a macro from a modulemod macros {#[macro_export]macro_rules!my_macro {() => {println!("Check out my macro!");};}}
Iterieren
// Iterate through a vectorlet my_fav_fruits =vec!["banana", "raspberry"];letmut my_iterable_fav_fruits = my_fav_fruits.iter();assert_eq!(my_iterable_fav_fruits.next(), Some(&"banana"));assert_eq!(my_iterable_fav_fruits.next(), Some(&"raspberry"));assert_eq!(my_iterable_fav_fruits.next(), None); // When it's over, it's none// One line iteration with actionmy_fav_fruits.iter().map(|x|capitalize_first(x)).collect()// Hashmap iterationfor (key, hashvalue) in&*map {for key in map.keys() {for value in map.values() {
Rekursive Box
enumList {Cons(i32, List),Nil,}let list =Cons(1, Cons(2, Cons(3, Nil)));
Conditionals
if
let n =5;if n <0 {print!("{} is negative", n);} elseif n >0 {print!("{} is positive", n);} else {print!("{} is zero", n);}
Übereinstimmung
match number {// Match a single value1=>println!("One!"),// Match several values2|3|5|7|11=>println!("This is a prime"),// TODO ^ Try adding 13 to the list of prime values// Match an inclusive range13..=19=>println!("A teen"),// Handle the rest of cases_ =>println!("Ain't special"),}let boolean =true;// Match is an expression toolet binary =match boolean {// The arms of a match must cover all the possible valuesfalse=>0,true=>1,// TODO ^ Try commenting out one of these arms};
letmut n =1;while n <101 {if n %15==0 {println!("fizzbuzz");} elseif n %5==0 {println!("buzz");} else {println!("{}", n);}n +=1;}
für
for n in1..101 {if n %15==0 {println!("fizzbuzz");} else {println!("{}", n);}}// Use "..=" to make inclusive both endsfor n in1..=100 {if n %15==0 {println!("fizzbuzz");} elseif n %3==0 {println!("fizz");} elseif n %5==0 {println!("buzz");} else {println!("{}", n);}}// ITERATIONSlet names =vec!["Bob", "Frank", "Ferris"];//iter - Doesn't consume the collectionfor name in names.iter() {match name {&"Ferris"=>println!("There is a rustacean among us!"),_ =>println!("Hello {}", name),}}//into_iter - COnsumes the collectionfor name in names.into_iter() {match name {"Ferris"=>println!("There is a rustacean among us!"),_ =>println!("Hello {}", name),}}//iter_mut - This mutably borrows each element of the collectionfor name in names.iter_mut() {*name =match name {&mut"Ferris"=>"There is a rustacean among us!",_ =>"Hello",}}
if let
let optional_word =Some(String::from("rustlings"));iflet word = optional_word {println!("The word is: {}", word);} else {println!("The optional word doesn't contain anything");}
while let
letmut optional =Some(0);// This reads: "while `let` destructures `optional` into// `Some(i)`, evaluate the block (`{}`). Else `break`.whileletSome(i) = optional {if i >9 {println!("Greater than 9, quit!");optional =None;} else {println!("`i` is `{:?}`. Try again.", i);optional =Some(i +1);}// ^ Less rightward drift and doesn't require// explicitly handling the failing case.}
Traits
Erstellen Sie eine neue Methode für einen Typ
traitAppendBar {fnappend_bar(self) -> Self;}implAppendBarforString {fnappend_bar(self) -> Self{format!("{}Bar", self)}}let s =String::from("Foo");let s = s.append_bar();println!("s: {}", s);
Ein Arc kann Clone verwenden, um weitere Referenzen auf das Objekt zu erstellen, um sie an die Threads weiterzugeben. Wenn der letzte Referenzzeiger auf einen Wert außerhalb des Gültigkeitsbereichs ist, wird die Variable gelöscht.
use std::sync::Arc;let apple =Arc::new("the same apple");for _ in0..10 {let apple =Arc::clone(&apple);thread::spawn(move|| {println!("{:?}", apple);});}
Threads
In diesem Fall werden wir dem Thread eine Variable übergeben, die er ändern kann.