ToB企服应用市场:ToB评测及商务社交产业平台

标题: Rust编程语言入门之泛型、Trait、生命周期 [打印本页]

作者: 反转基因福娃    时间: 2023-4-4 14:37
标题: Rust编程语言入门之泛型、Trait、生命周期
泛型、Trait、生命周期

一、提取函数消除重复
  1. fn main() {
  2.   let number_list = vec![34, 50, 25, 100, 65];
  3.   let mut largest = number_list[0];
  4.   for number in number_list {
  5.     if number > largest {
  6.       largest = number;
  7.     }
  8.   }
  9.   
  10.   println!("The largest number is {}", largest);
  11. }
复制代码
重复代码

  1. fn largest(list: &[i32]) -> i32 {
  2.   let mut largest = list[0];
  3.   for &item in list { // &item 解构
  4.     if item > largest {
  5.       largest = item;
  6.     }
  7.   }
  8.   largest
  9. }
  10. fn main() {
  11.   let number_list = vec![34, 50, 25, 100, 65];
  12.   let result = largest(&number_list);
  13.   println!("The largest number is {}", result);
  14.   
  15.   let number_list = vec![102, 34, 6000, 89, 54, 2, 43, 8];
  16.   let result = largest(&number_list);
  17.   println!("The largest number is {}", result);
  18. }
复制代码
消除重复的步骤

二、泛型

泛型

函数定义中的泛型

  1. fn largest<T>(list: &[T]) -> T {
  2.   let mut largest = list[0];
  3.   for &item in list {
  4.     if item > largest {  // 比较 报错 ToDo
  5.       largest = item;
  6.     }
  7.   }
  8.   largest
  9. }
  10. fn main() {
  11.   let number_list = vec![34, 50, 25, 100, 65];
  12.   let result = largest(&number_list);
  13.   println!("The largest number is {}", result);
  14.   
  15.   let char_list = vec!['y', 'm', 'a', 'q'];
  16.   let result = largest(&char_list);
  17.   println!("The largest number is {}", result);
  18. }
复制代码
Struct 定义中的泛型
  1. struct Point<T> {
  2.   x: T,
  3.   y: T,
  4. }
  5. struct Point1<T, U> {
  6.   x: T,
  7.   y: U,
  8. }
  9. fn main() {
  10.   let integer = Point {x: 5, y: 10};
  11.   let float = Point(x: 1.0, y: 4.0);
  12.   
  13.   let integer1 = Point1 {x: 5, y: 10.0};
  14. }
复制代码
Enum 定义中的泛型

  1. enum Option<T> {
  2.   Some(T),
  3.   None,
  4. }
  5. enum Result<T, E> {
  6.   Ok(T),
  7.   Err(E),
  8. }
  9. fn main() {}
复制代码
方法定义中的泛型

  1. struct Point<T> {
  2.   x: T,
  3.   y: T,
  4. }
  5. impl<T> Point<T> {
  6.   fn x(&self) -> &T {
  7.     &self.x
  8.   }
  9. }
  10. impl Point<i32> {
  11.   fn x1(&self) -> &i32 {
  12.     &self.x
  13.   }
  14. }
  15. fn main() {
  16.   let p = Point {x: 5, y: 10};
  17.   println!("p.x = {}", p.x());
  18. }
复制代码
  1. struct Point<T, U> {
  2.   x: T,
  3.   y: U,
  4. }
  5. impl<T, U> Point<T, U> {
  6.   fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W> {
  7.     Point {
  8.       x: self.x,
  9.       y: other.y,
  10.     }
  11.   }
  12. }
  13. fn main() {
  14.   let p1 = Point {x: 5, y: 4};
  15.   let p2 = Point {x: "Hello", y: 'c'};
  16.   let p3 = p1.mixup(p2);
  17.   
  18.   println!("p3.x = {}, p3.y = {}", p3.x, p3.y);
  19. }
复制代码
泛型代码的性能

  1. fn main() {
  2.   let integer = Some(5);
  3.   let float = Some(5.0);
  4. }
  5. enum Option_i32 {
  6.   Some(i32),
  7.   None,
  8. }
  9. enum Option_f64 {
  10.   Some(f64),
  11.   None,
  12. }
  13. fn main() {
  14.   let integer = Option_i32::Some(5);
  15.   let float = Option_f64::Some(5.0);
  16. }
复制代码
三、Trait(上)

Trait

定义一个 Trait

  1. pub trait Summary {
  2.   fn summarize(&self) -> String;
  3. }
  4. // NewsArticle
  5. // Tweet
  6. fn main() {}
复制代码
在类型上实现 trait

lib.rs 文件
  1. pub trait Summary {
  2.   fn summarize(&self) -> String;
  3. }
  4. pub struct NewsArticle {
  5.   pub headline: String,
  6.   pub location: String,
  7.   pub author: String,
  8.   pub content: String,
  9. }
  10. impl Summary for NewsArticle {
  11.   fn summarize(&self) -> String {
  12.     format!("{}, by {} ({})", self.headline, self.author, self.location)
  13.   }
  14. }
  15. pub struct Tweet {
  16.   pub username: String,
  17.   pub content: String,
  18.   pub reply: bool,
  19.   pub retweet: bool,
  20. }
  21. impl Summary for Tweet {
  22.   fn summarize(&self) -> String {
  23.     format!("{}: {}", self.username, self.content)
  24.   }
  25. }
复制代码
main.rs 文件
  1. use demo::Summary;
  2. use demo::Tweet;
  3. fn main() {
  4.   let tweet = Tweet {
  5.     username: String::from("horse_ebooks"),
  6.     content: String::from("of course, as you probably already know, people"),
  7.     reply: false,
  8.     retweet: false,
  9.   };
  10.   
  11.   println!("1 new tweet: {}", tweet.summarize())
  12. }
复制代码
实现 trait 的约束

默认实现

lib.rs 文件
  1. pub trait Summary {
  2.   // fn summarize(&self) -> String;
  3.   fn summarize(&self) -> String {
  4.     String::from("(Read more...)")
  5.   }
  6. }
  7. pub struct NewsArticle {
  8.   pub headline: String,
  9.   pub location: String,
  10.   pub author: String,
  11.   pub content: String,
  12. }
  13. impl Summary for NewsArticle {
  14.   // fn summarize(&self) -> String {
  15.    // format!("{}, by {} ({})", self.headline, self.author, self.location)
  16.   // }
  17. }
  18. pub struct Tweet {
  19.   pub username: String,
  20.   pub content: String,
  21.   pub reply: bool,
  22.   pub retweet: bool,
  23. }
  24. impl Summary for Tweet {
  25.   fn summarize(&self) -> String {
  26.     format!("{}: {}", self.username, self.content)
  27.   }
  28. }
复制代码
main.rs 文件
  1. use demo::NewsArticle;
  2. use demo::Summary;
  3. fn main() {
  4.   let article = NewsArticle {
  5.     headline: String::from("Penguins win the Stanley Cup Championship!"),
  6.     content: String::from("The pittsburgh penguins once again are the best hockey team in the NHL."),
  7.     author: String::from("Iceburgh"),
  8.     location: String::from("Pittsburgh, PA, USA"),
  9.   };
  10.   
  11.   println!("1 new tweet: {}", article .summarize())
  12. }
复制代码
  1. pub trait Summary {
  2.   fn summarize_author(&self) -> String;
  3.   
  4.   fn summarize(&self) -> String {
  5.     format!("Read more from {} ...", self.summarize_author())
  6.   }
  7. }
  8. pub struct NewsArticle {
  9.   pub headline: String,
  10.   pub location: String,
  11.   pub author: String,
  12.   pub content: String,
  13. }
  14. impl Summary for NewsArticle {
  15.   fn summarize_author(&self) -> String {
  16.     format!("@{}", self.author)
  17.   }
  18. }
复制代码
四、Trait(下)

Trait 作为参数
  1. pub fn notify(item: impl Summary) {
  2.   println!("Breaking news! {}", item.summarize());
  3. }
复制代码
  1. pub fn notify<T: Summary>(item: T) {
  2.   println!("Breaking news! {}", item.summarize());
  3. }
复制代码
  1. pub fn notify(item: impl Summary + Display) {  println!("Breaking news! {}", item.summarize());}pub fn notify<T: Summary>(item: T) {
  2.   println!("Breaking news! {}", item.summarize());
  3. }
复制代码
  1. pub fn notify<T: Summary + Display, U: Clone + Debug>(a: T, b: U) -> String {
  2.   format!("Breaking news! {}", a.summarize())
  3. }
  4. pub fn notify<T, U>(a: T, b: U) -> String
  5. where
  6.         T: Summary + Display,
  7.         U: Clone + Debug,
  8. {
  9.   format!("Breaking news! {}", a.summarize())
  10. }
复制代码
实现 Trait 作为返回类型

  1. pub fn notify1(s: &str) -> impl Summary {
  2.   NewsArticle {
  3.     headline: String::from("Penguins win the Stanley Cup Championship!"),
  4.     content: String::from("The Pittsburgh Penguins once again are the best hockey team in the NHL."),
  5.     author: String::from("Iceburgh"),
  6.     location: String::from("Pittsburgh, PA, USA"),
  7.   }
  8. }
复制代码
使用 Trait Bound 的例子

  1. fn largest<T: PartialOrd + Clone>(list: &[T]) -> T {
  2.   let mut largest = list[0].clone();
  3.   
  4.   for item in list.iter() {
  5.     if item > &largest { // std::cmp::ParticalOrd
  6.       largest = item.clone();
  7.     }
  8.   }
  9.   
  10.   largest
  11. }
  12. fn main() {
  13.   let number_list = vec![34, 50, 25, 100, 65];
  14.   let result = largest(&number_list);
  15.   println!("The largest number is {}", result);
  16.   
  17.   let char_list = vec!['y', 'm', 'a', 'q'];
  18.   let result = largest(&char_list);
  19.   println!("The largest char is {}", result)
  20. }
  21. fn largest<T: PartialOrd + Clone>(list: &[T]) -> &T {
  22.   let mut largest = &list[0];
  23.   
  24.   for item in list.iter() {
  25.     if item > &largest { // std::cmp::ParticalOrd
  26.       largest = item;
  27.     }
  28.   }
  29.   
  30.   largest
  31. }
  32. fn main() {
  33.   let str_list = vec![String::from("hello"), String::from("world")];
  34.   let result = largest(&str_list);
  35.   println!("The largest word is {}", result);
  36.   
  37. }
复制代码
使用 Trait Bound 有条件的实现方法

  1. use std::fmt::Display;
  2. struct Pair<T> {
  3.   x: T,
  4.   y: T,
  5. }
  6. impl<T> Pair<T> {
  7.   fn new(x: T, y: T) -> Self {
  8.     Self {x, y}
  9.   }
  10. }
  11. impl<T: Display + PartialOrd> Pair<T> {
  12.   fn cmp_display(&self) {
  13.     if self.x >= self.y {
  14.       println!("The largest member is x = {}", self.x);
  15.     } else {
  16.       println!("The largest member is y = {}", self.y);
  17.     }
  18.   }
  19. }
复制代码
  1. fn main() {
  2.   let s = 3.to_string();
  3. }
复制代码
五、生命周期(1/4)

生命周期

生命周期 - 避免悬垂引用(dangling regerence)

  1. fn main() {
  2.   {
  3.     let r;
  4.     {
  5.       let x = 5;
  6.       r = &x; // 报错
  7.     }
  8.     println!("r: {}", r);
  9.   }
  10. }
复制代码
借用检查器

  1. fn main() {
  2.   let x = 5;
  3.   let r = &x;
  4.   
  5.   println!("r: {}", r);
  6. }
复制代码
函数中的泛型生命周期
  1. fn main() {
  2.   let string1 = String::from("abcd");
  3.   let string2 = "xyz";
  4.   
  5.   let result = longest(string1.as_str(), string2);
  6.   
  7.   println!("The longest string is {}", result);
  8. }
  9. fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
  10.   if x.len() > y.len() {
  11.     x
  12.   } else {
  13.     y
  14.   }
  15. }
复制代码
六、生命周期(2/4)

生命周期标注语法

生命周期标注 - 语法

生命周期标注 - 例子

函数签名中的生命周期标注

  1. fn main() {
  2.   let string1 = String::from("abcd");
  3.   let result;
  4.   {
  5.     let string2 = String::from("xyz");
  6.     let result = longest(string1.as_str(), string2.as_str());  // 报错 string2
  7.   }
  8.   println!("The longest string is {}", result);
  9. }
  10. fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
  11.   if x.len() > y.len() {
  12.     x
  13.   } else {
  14.     y
  15.   }
  16. }
复制代码
七、生命周期(3/4)

深入理解生命周期

  1. fn main() {
  2.   let string1 = String::from("abcd");
  3.   let string2 = "xyz";
  4.   
  5.   let result = longest(string1.as_str(), string2);
  6.   
  7.   println!("The longest string is {}", result);
  8. }
  9. fn longest<'a>(x: &'a str, y: &str) -> &'a str {
  10.   x
  11. }
复制代码
  1. fn main() {
  2.   let string1 = String::from("abcd");
  3.   let string2 = "xyz";
  4.   
  5.   let result = longest(string1.as_str(), string2);
  6.   
  7.   println!("The longest string is {}", result);
  8. }
  9. fn longest<'a>(x: &'a str, y: &str) -> &'a str {
  10.   let result = String::from("abc");
  11.   result.as_str()  // 报错
  12. }
  13. fn longest<'a>(x: &'a str, y: &str) -> String {
  14.   let result = String::from("abc");
  15.   result
  16. }
复制代码
Struct 定义中的生命周期标注

  1. struct ImportantExcerpt<'a> {
  2.   part: &'a str,
  3. }
  4. fn main() {
  5.   let novel = String::from("Call me Ishmael. Some years ago ...")
  6.   
  7.   let first_sentence = novel.split('.')
  8.           .next()
  9.           .expect("Could not found a '.'");
  10.   
  11.   let i = ImportantExcerpt {
  12.     part: first_sentence
  13.   };
  14. }
复制代码
静态生命周期

泛型参数类型、Trait Bound、生命周期
  1. struct ImportantExcerpt<'a> {
  2.   part: &'a str,
  3. }
  4. impl<'a> ImportantExcerpt<'a> {
  5.   fn level(&self) -> i32 {
  6.     3
  7.   }
  8.   
  9.   fn snnounce_and_return_part(&self, announcement: &str) -> &str {
  10.     println!("Attention please: {}", announcement);
  11.     self.part
  12.   }
  13. }
  14. fn main() {
  15.   let novel = String::from("Call me Ishmael. Some years ago ...")
  16.   
  17.   let first_sentence = novel.split('.')
  18.           .next()
  19.           .expect("Could not found a '.'");
  20.   
  21.   let i = ImportantExcerpt {
  22.     part: first_sentence,
  23.   };
  24. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4