<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Rust體驗

      Posted on 2023-03-24 22:03  呱呱呱呱嘰里呱啦  閱讀(57)  評論(0)    收藏  舉報

      Rust體驗

      Hello World

      fn main() {
          println!("Hello, world!");
      }
      

      概述

      Rust是靜態強類型語言

      變量

      fn main() {
          let x = 5;  // 默認整數類型i32
          println!("x: {}", x);
          // x = 6; 沒有被關鍵字mut修飾的變量不可以修改值,即變量默認不可變
          let x = x + 5;  // x shadowed by x
          println!("x: {}", x);
      
          let mut y = 5;
          println!("y: {}", y);
          y = 6;
          println!("y: {}", y);
      
          const CONST:i32 = 6 + 8;  // 常量可以使用編譯器能夠直接計算得出結果的表達式作為值,但不可使用運行時才可知的表達式作為值
          println!("CONST: {}", CONST);
      }
      

      基本數據類型

      fn main() {
          // 整數類型包括12種:8-128bit的有符號(i)和無符號(u)類型、根據操作系統位數決定的isize、usize類型,默認i32
          // 浮點數類型包括兩種:f32和f64類型,默認為f64類型
          // 布爾類型包括兩個值:true、false,大小為一個字節
          // 字符類型可以使用''包裹單字符(utf-8字符集內)
          let x = 6;  // i32
          let y: u8 = 6;
          let z = 3.6; // f64
          let b = true;
          let c = '??';
          println!("x:{};y:{};z:{};b:{};c:{}", x, y, z, b, c)
      }
      // 注意,debug模式下會在編譯時檢查整數溢出,release模式下會忽略整數溢出
      

      容器類型

      元組

      fn main() {
          // 元組,一個擁有固定長度的可以包含多類型的容器
          let tup = (1, 'a');
          let (x, y) = tup;
          println!("x:{}; y:{}", x, y);
          println!("x:{}; y:{}", tup.0, tup.1);
      }
      

      數組

      fn main() {
          // 數組,一個擁有固定長度的相同類型元素的容器
          let a:[i8; 6] = [1, 2, 3, 4, 5, 6];
          let b:[i8; 6*1] = [6; 6*1];
          println!("{}", a[0]);
          println!("{}", b[0]);
      
          // 要修改數組中的元素,需要將數組聲明為可變數組
          let mut c:[i8; 2] = [6, 8];
          c[1] = 10;
          println!("{}", c[1])
      }
      

      切片

      fn main() {
          // 切片,對數組的部分引用(很像golang中的切片是對底層數組的view)
          let arr:[u8;6] = [1, 2, 3, 4, 5, 6];
          let s = &arr[0..3];  // &表引用,..類似于python中的:
          println!("s[0]:{}, len(s):{}", s[0], s.len());
          let s1 = &s[s.len()-2..];
          println!("s[-2]:{}", s1[0]);
      
          // 通過切片修改底層數組元素需要底層數組也是mutable
          let mut arr2:[u8;6] = [1, 2, 3, 4, 5, 6];
          let s2 = &mut arr2[0..3];
          s2[0] = 0;
          println!("arr2[0]: {}", arr2[0])
      }
      

      結構體

      #[derive(Debug)]  // 派生屬性
      // 結構體
      struct Cat {
          age: u8,
          color: String,
      }
      
      
      fn main() {
          // 切片,對數組的部分引用(很像golang中的切片是對底層數組的view)
          let cat = Cat { age: 3, color: "三花".to_string() };
          println!("age: {}; color: {}", cat.age, cat.color);
          println!("{:?}", cat)
      }
      

      枚舉

      #[derive(Debug)]  // 派生屬性
      enum Log {
          Project,
          Task,
      }
      
      enum Task {
          Read = 1,
          Write = 2,
      }
      
      enum Cat {
          CatWithNum(u8, String, u8),
          CatWithoutNum(u8, String),
      }
      
      fn main() {
          let cat: Cat = Cat::CatWithNum(3, "三花".to_string(), 1);
          match cat{
              Cat::CatWithNum(age, color, num) => {
                  println!("age:{}; color:{}; num:{}", age, color, num)
              }
              Cat::CatWithoutNum(age, color) => {
                  println!("age:{}; color:{}", age, color)
              }
          }
      }
      

      類型轉換

      use std::mem;
      
      // 派生屬性
      fn main() {
          // 類型轉換
          let a: i8 = -1;
          let b = a as u8;
          println!("b:{}", b);
      
          let c: u16 = 258;
          let d = c as u8;
          println!("d:{}", d);  // 2
          let e = c as u32;
          println!("e:{}", e);  // 258
      
          // transmute,直接指示編譯器將內存中的某些數據以區別于原類型的另一種類型來處理
          let a = [0u8, 1u8, 0u8, 0u8, ];
          unsafe {
              let b: u32 = mem::transmute(a);
              println!("{}", b)  // 256
          }
      }
      

      流程控制

      fn main() {
          // 表達式,除聲明語句之外的其他絕大部分代碼在Rust中都被視為表達式,這也意味著這些代碼會有返回值
          let a = if true {
              'a'
          } else {
              'b'
          };
          println!("a: {}", a);
      }
      

      if-else

      fn main() {
          // if-else表達式,當if-else表達式返回值被接收時,才可以在if-else的分支代碼塊中返回值,且各分支中的返回值必須相同類型
          let x = true;
          if x {
              println!("{}", 6);
          } else {
              println!("{}", 8);
          }
          let y = if x {
              x
          } else {
              false
          };
          println!("{}", y);
      }
      

      loop

      fn main() {
          // loop循環
          let mut sum = 0;
          let mut counter = 1;
          let res = loop {
              sum += counter;
              counter += 1;
              if counter > 100 {break sum / counter}
          };
          println!("sum: {}", sum);
          println!("res: {}", res);
      }
      

      while

      fn main() {
          // while循環
          let mut sum = 0;
          let mut counter = 1;
          while counter < 101 {
              sum += counter;
              counter += 1;
          }
          println!("sum: {}", sum)
      }
      

      for range

      fn main() {
          // for range,相當類似python中的for range語法
          for i in 0..3 {  // 左閉右開區間
              println!("{}", i)
          }
          for i in 0..=3 {  // 閉區間
              println!("{}", i)
          }
      
          let mut arr = [1, 2, 3];
          for i in arr.iter() {  // iter()會返回迭代器
              println!("{}", i)
          }
      
          for i in arr.iter_mut() {  // 可修改元素
              *i *= 2  // *i = *i * 2
          }
          for i in arr.iter() {
              println!("{}", i)
          }
      }
      

      match

      fn main() {
          // match
          let m = 'x';
          match m {
              'a' => {
                  println!("'a'")
              },
              _ => {  // default
                  println!("'{}'", m)
              }
          }
      
      }
      

      if-let語法糖

      enum Gender {
          M(String),
          F,
      }
      
      
      fn main() {
          // if-let語法糖
          let gender = Gender::M("George".to_string());
          if let Gender::M(s) = gender {
              println!("{}", s);
          }
      }
      

      while-let語法糖

      #[derive(Debug)]
      enum Gender {
          M,
          F,
      }
      
      
      fn main() {
          // while-let語法糖
          let gender = Gender::M;
          let mut counter = 1;
          while let Gender::M = gender {
              println!("{:?}", gender);
              counter += 1;
              if counter == 11 {break}
          }
      }
      

      函數

      普通函數和方法

      #[derive(Debug)]
      struct Cat {
          age: u8,
          color: String,
      }
      
      impl Cat {
          fn new(age: u8, color: String) -> Cat {
              Cat{age, color}
          }
          fn say_my_age(&self) {
              println!("我現在{}歲了", self.age)
          }
          fn new_age(&mut self, age: u8) {
              self.age = age;
              self.say_my_age()
          }
      }
      
      
      fn handle_fbn(i: u64) -> u64 {
          if i < 2 {
              i
          } else {
              handle_fbn(i - 1) + handle_fbn(i - 2)
          }
      }
      
      fn main() {
          // 函數
          println!("{}", handle_fbn(3));
          let cat = Cat::new(3, "三花".to_string());
          println!("{:?}", cat);
          let mut cat2 = Cat{ age: 3, color: "四花".to_string() };
          cat2.new_age(4);
      }
      

      閉包

      // 使用 |var| -> res {func body}定義閉包函數并可賦值給變量
      use std::thread;
      
      fn main() {
          let n = 1;
          thread::spawn(move || {
              println!("{}", n);
          }).join().unwrap();
      }
      

      高階函數

      即參數或者返回值中包含函數的函數

      fn opt(f: fn(i32, i32) -> i32, a: i32, b: i32) -> i32 {
          f(a, b)
      }
      
      fn add(a: i32, b: i32) -> i32 {
          a + b
      }
      
      fn sub(a: i32, b: i32) -> i32 {
          a - b
      }
      
      fn main() {
          println!("{}", opt(add, 1, 2));
          println!("{}", opt(sub, 1, 2));
      }
      

      發散函數

      一個以!標志其返回空類型的永遠不會返回的函數,可以用來綁定任意類型的接收者。

      猜數游戲

      use std::io;
      use rand::Rng;
      
      fn main() {
          let answer: u32 = rand::thread_rng().gen_range(1..101);
          println!("猜數游戲開始");
          loop {
              println!("請輸入你猜的數字:");
              let mut in_str = String::new();
              io::stdin().read_line(&mut in_str).unwrap();
              let in_num: u32 = match in_str.trim().parse() {
                  Ok(num) => num,
                  Err(_err) => continue
              };
              println!("您輸入的數字是:{}", in_num);
              if in_num > answer {
                  println!("答錯了,輸入的數字比正確答案大。");
              } else if in_num < answer {
                  println!("答錯了,輸入的數字比正確答案小。");
              } else {
                  println!("恭喜你,答對了。");
                  break;
              }
          }
      }
      

      代碼組織

      package

      使用cargo new來創建的用于管理一個或者多個crate的結構;

      main.rs、lib.rs即與所屬package同名的二進制或者庫crate的入口;

      crate

      rust的最小編譯單元;

      module

      在crate中組織獨立代碼塊的結構;

      pub

      成員默認私有,pub用來定義可見性:

      pub 模塊可見

      pub(self) 當前直接所屬子模塊可見

      pub(crate) 當前crate可見

      fn add1(a: i32, b: i32) -> i32 {
          a + b
      }
      
      mod mod1 {
          pub fn add(a: i32, b: i32) -> i32 {
              a + b
          }
      
          fn add1(a: i32, b: i32) -> i32 {
              a + b
          }
      
          pub mod mod2 {
              fn add1(a: i32, b: i32) -> i32 {
                  println!("mod1::mod2::add1");
                  a + b
              }
      
              pub fn add2(a: i32, b: i32) -> i32 {
                  super::add1(a, b)
              }
      
              pub fn add3(a: i32, b: i32) -> i32 {
                  println!("調用來自mod2的add1");
                  add1(a, b)  // 等同于 self::add1(a, b)
              }
          }
      }
      
      fn main() {
          println!("{}",add1(1, 2));
          println!("{}", mod1::add(1, 2));
          // println!("{}", mod1::add1(1, 2)) add1 is private.
          println!("{}", mod1::mod2::add2(1, 2));
          println!("{}", mod1::mod2::add3(1, 2));
      }
      
      mod mod1 {
          pub struct Cat {
              pub age: u8,
              color: String,
          }
      
          impl Cat {
              pub fn new(age: u8, color: &str) -> Cat {
                  Cat { age, color: String::from(color) }
              }
              fn set_age(&mut self, age: u8) {
                  self.age = age;
              }
      
              pub fn set_cat(&mut self, age: u8, color: &str) {
                  self.set_age(age);
                  self.color = String::from(color);
              }
          }
      }
      
      fn main() {
          let mut cat = mod1::Cat::new(3, "三花");
          cat.set_cat(5, "四花");
          // cat.set_age(6); Method `set_age` is private.
          // println!("{}", cat.color); field `color` of struct `Cat` is private.
      }
      

      模塊映射

      類似于python中的模塊,你可以將一個.rs文件通過文件名的形式聲明引用:mod mod1;。

      也可以將模塊映射到文件夾,即在某個文件夾下直接創建mod.rs(約定的文件名),可以通過文件夾名引用:mod mod2;。

      引用modx.rs中的標識符時可以用:println!("{}", mod2::modx::something),需要在mod.rs中pub聲明modx

      ./src

      -main.rs
      
      -mod1.rs
      
      mod2
      
          -mod.rs
      
          -modx.rs
      

      泛型

      泛型,個人理解,是對強類型語言、靜態語言的類型確定這種(在運行時的優點但)在代碼組織上的缺點的一種優化,完全明確而具體的類型可能會使代碼出現冗余,所以需要可以承載不同具體類型的共同特征的一種形式,來對不同類型的傳參或者屬性賦值進行代碼復用。

      這里本人聯想到python或者其他語言中的鴨子類型,鴨子類型與泛型似乎有異同點:

      相同:都是對代碼書寫、組織的靈活性的一種支持;都是對不同具體類型的共同特征的提取和發布

      不同:鴨子類型強調行為的一致性或者說相同點,泛型并不單獨強調行為或者屬性,而只強調共同特征;鴨子類型不一定需要標注式的參數來實現,但泛型需要這種類型參數來實現(這種類型參數需要從函數、結構體、代碼塊的起始位置聲明向內部傳遞才可以使用)

      fn gt<T: PartialOrd>(a: T, b: T) -> T {
          if a > b { a } else { b }
      }
      
      struct Cat<T, U> {
          // 僅為演示,但實際編碼中應該拆分結構體以確保每個結構體中的泛型參數少些
          age: T,
          color: U,
      }
      
      struct TwoNums<T> {
          a: T,
          b: T,
      }
      
      impl<T: Clone + PartialOrd> TwoNums<T> {
          fn gt(&self) -> T {
              if self.a > self.b { self.a.clone() } else { self.b.clone() }
          }
      }
      
      // 為具體類型實現方法(奇奇怪怪的想法,使用泛型又要單獨實現具體類型的方法),估計是為了少數特殊需求
      impl TwoNums<u8> {
          fn sub(&self) -> (u8, bool) {
              self.a.overflowing_sub(self.b)
          }
      }
      
      fn main() {
          println!("{}", gt(1, 2));
          println!("{}", gt(1.1, 2.2));
          let cat = Cat {
              age: 3,
              color: "三花".to_string(),
          };
          println!("{}, {}", cat.age, cat.color);
          let tn = TwoNums { a: 1, b: 2 };
          println!("{}", tn.gt());
          // let tn1 = TwoNums { a: 255, b: 256 }; b out of u8.
          let tn1 = TwoNums { a: 254, b: 255 };
          println!("{}, {}", tn1.sub().0, tn1.sub().1)
      }
      

      traits

      類似于go中的接口,用來定義共同的行為

      use std::fmt::Formatter;
      
      struct Cat<T, U> {
          // 僅為演示,但實際編碼中應該拆分結構體以確保每個結構體中的泛型參數少些
          age: T,
          color: U,
      }
      
      impl<T: std::fmt::Display, U: std::fmt::Display> std::fmt::Display for Cat<T, U> {
          fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
              write!(f, "貓的年齡:{},貓的毛色:{}", self.age, self.color)
          }
      }
      
      // 要求參數已經實現的traits
      fn print_cat(cat: impl std::fmt::Display) {
          println!("{}", cat)
      }
      
      fn main() {
          let cat = Cat { age: 3, color: "三花" };
          println!("{}", cat);
          print_cat(cat);
      }
      

      派生

      編譯期的動作,不會有運行時開銷

      #[derive(Debug, PartialEq, Default)]  // `Cat` has derived impl for the traits `Debug`、`PartialEq`、`Default`.僅修飾struct Cat。
      struct Cat {
          age: u8,
          color: String,
      }
      
      
      fn main() {
          let cat = Cat { age: 3, color: "三花".to_string() };
          println!("{}, {}", cat.age, cat.color);
          println!("{:?}", cat);
          let cat2 = Cat { age: 3, color: "三花".to_string() };
          println!("{}", cat == cat2);
          let cat3 = Cat::default();
          println!("{:?}", cat3);
      }
      

      其他理論

      所有權

      用來兼顧GC方便和性能的概念。

      作用域

      即使用"{}"包裹的代碼塊

      fn main() {
          // 一個值只能由一個變量持有所有權
          // 值離開變量所在的作用域會被銷毀
          let s = String::from("cat");
          let s1 = s; // "cat"所有權轉移至s2即s1喪失"cat"的所有權
          // println!("{}", s); borrow of moved value: `s`.
          println!("{}", s1);
      
      
          let s2 = String::from("cat");
          let s3 = &s2; // borrow from s2.
          println!("{}", s2);
          println!("{}", s3);
      
          // 無法從不可變變量獲取可變引用
          let _s4 = String::from("cat");
          // let s5 = &mut s4; // cannot borrow `s4` as mutable, as it is not declared as mutable.
          let mut s5 = String::from("cat");
          let s6 = &mut s5;
          s6.push_str("cat");
          println!("{}", s6);
      
          // 同一個變量同時只能被取得一個可變引用
          let mut s7 = String::from("cat");
          let s8 = &mut s7;
          // let s9 = &mut s7; cannot borrow `s7` as mutable more than once at a time. 當有代碼調用s9時此處會報錯。
          println!("{}", s8);
      
      }
      

      生命周期

      struct Cat<'a> {
          color: &'a str,  //color: &str, will get missing lifetime specifier
      }
      
      fn main() {
          let cat = Cat { color: "三花" };
          println!("{}", cat.color)
      }
      

      錯誤處理

      Rust的錯誤處理類似于Golang,Golang區分了錯誤和異常的含義,將錯誤定義為正常程序的一部分,是可以被預知或處理的,而將異常定義為程序邏輯自身的錯誤。Rust則更直接得將錯誤定義為可恢復的錯誤,將異常定義為不可恢復的錯誤。

      不可恢復的錯誤

      fn main() {
          // 不可恢復錯誤
          // panic!("GG");  // 1. panic.
          // assert!(false);  // 2. assertion failed.
          // unimplemented!();  // 3. not implemented.
          // unreachable!();  // 4. 運行到預計不應該運行的代碼
      }
      

      可恢復的錯誤

      fn main() {
          match std::fs::read("not_exist.txt") {
              Ok(content) => println!("{}", std::str::from_utf8(&content).unwrap()),
              Err(err) => println!("{}", err)
          }
      }
      

      ?表達式

      fn make_err() -> Result<u8, String> {
          Err("三花".to_string())
      }
      
      fn get_err() -> Result<u8, String> {
          let _ = make_err()?;
          Ok(1)
      }
      
      fn main() {
          println!("{:?}", get_err())
      }
      

      內建資源

      Box智能指針

      fn main() {
          let _n = Box::new(6);
          // 與let _n = 6;并無不同
          // Box返回指針這個特性決定了接收者長度一定,應該在需要長度一定的屬性或者元素但這些元素或者屬性本身的值長度不一定時使用
      }
      
      #[derive(Debug)]
      enum List {
          Cons(i32, Box<List>),
          Nil,
      }
      
      use crate::List::{Cons, Nil};
      
      fn main() {
          let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
          println!("{:?}", list)
      }
      
      

      Rc-帶引用計數的智能指針

      rc智能指針可以通過安全的通過引用計數銷毀內存的方式實現一個值存在多個所有者。

      enum List {
          Cons(i32, Rc<List>),
          Nil,
      }
      
      use crate::List::{Cons, Nil};
      use std::rc::Rc;
      
      fn main() {
          let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil)))));
          println!("創建a后計數 {}", Rc::strong_count(&a));  // 1  Rc::strong_count(&a) == a.clone()
          let _b = Cons(3, Rc::clone(&a));
          println!("創建b后計數  {}", Rc::strong_count(&a));  // 2
          {
              let _c = Cons(4, Rc::clone(&a));
              println!("創建c后計數 {}", Rc::strong_count(&a));  // 3
          }
          println!("跳出c代碼塊后計數 = {}", Rc::strong_count(&a));  // 2
      }
      

      Vector

      fn main() {
          let mut v: Vec<u8> = Vec::new();
          for i in 0..6 {
              v.push(i)
          }
          println!("{}", v.len());
      
          for i in v.iter() {
              println!("{}", i)
          }
      }
      

      HashMap

      use std::collections::HashMap;
      
      fn main() {
          let mut m:HashMap<&str, u8> = HashMap::new();
          m.insert("cat1", 3);
          m.insert("cat2", 4);
          for (name, &age) in m.iter() {  // 無序遍歷
              println!("name: {}, age: {}", name, age)
          }
      }
      

      Time

      原生time比較簡單,具體的功能建議直接chrono。

      use std::thread::sleep;
      use std::time::{Duration, SystemTime};
      
      fn main() {
          let now = SystemTime::now();
          println!("{:?}", now);
          sleep(Duration::from_secs(3));
          println!("{:?}", now.elapsed().unwrap());
      }
      
      主站蜘蛛池模板: 无码专区 人妻系列 在线| 超碰伊人久久大香线蕉综合| 国产日韩AV免费无码一区二区三区| 久久精品国产亚洲AV麻豆长发| 台山市| 国产一区国产二区在线视频| 久久人与动人物a级毛片 | 蜜桃av多人一区二区三区| 华坪县| 福利一区二区不卡国产| 91福利视频一区二区| 国产精品久久久久7777按摩| 久久亚洲av成人一二三区| 白嫩少妇无套内谢视频| 午夜无码免费福利视频网址| 亚洲最大激情中文字幕| 国产成人亚洲欧美二区综合| 临桂县| gogogo高清在线播放免费| 一本一本久久A久久精品综合不卡| 弋阳县| 开心五月激情综合久久爱| 在线精品视频一区二区三四| 精品人妻中文字幕av| 和艳妇在厨房好爽在线观看| 亚洲人妻系列中文字幕| 湖北省| 国产超碰无码最新上传| 亚洲精品国产中文字幕| 人人人澡人人肉久久精品| 久久精品色一情一乱一伦| 任我爽精品视频在线播放| 国产在线精品一区二区夜色| 日本乱一区二区三区在线| 精品国产污污免费网站| 精品国产第一国产综合精品| 欧美综合婷婷欧美综合五月 | 男人的天堂av一二三区| 成人国产精品免费网站| 日韩高清不卡一区二区三区| 亚洲a免费|