在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
Every programming language has tools for effectively handling the duplication of concepts. In Rust, one such tool is generics. Generics are abstract stand-ins for concrete types or other properties. 泛型的作用:降低代码冗余
Traits: Defining Shared BehaviorA trait tells the Rust compiler about functionality a particular type has and can share with other types. We can use traits to define shared behavior in an abstract way. We can use trait bounds to specify that a generic can be any type that has certain behavior. Note: Traits are similar to a feature often called interfaces in other languages, although with some differences.
#![allow(unused)] pub trait Person { fn food(&self) -> String; fn eat(&self) -> String { format!("(eat {}...)", self.food()) } } pub struct Teacher { pub name: String, } impl Person for Teacher { fn food(&self) -> String { format!("{}", "面包") } } pub struct Student { pub username: String, pub age: i8, } impl Person for Student { fn food(&self) -> String { format!("{}", "水果") } } pub fn test(){ let tch = Teacher { name: String::from("a01"), }; println!("teacher: {}", tch.eat()); let st = Student { username: String::from("Penguins win the Stanley Cup Championship!"), age: 12, }; println!("student: {}", st.eat()); }
mod tra; fn main() { println!("----------------"); tra::tra1::test(); }
输出 ----------------
Traits as ParametersNow that you know how to define and implement traits, we can explore how to use traits to define functions that accept many different types. pub fn notify_eat(item: &impl Person) { println!("notify: {}", item.eat()); } pub fn test2(){ let tch = Teacher { name: String::from("a01"), }; notify_eat(&tch); let st = Student { username: String::from("Penguins win the Stanley Cup Championship!"), age: 12, }; notify_eat(&st); } ----------------
notify: (eat 面包...)
notify: (eat 水果...)
Trait Bound Syntaxpub fn notify<T: Person>(item: &T) { println!("notify: {}", item.eat()); } pub fn test3(){ let tch = Teacher { name: String::from("a01"), }; notify(&tch); let st = Student { username: String::from("hong yun"), age: 12, }; notify(&st); } ----------------
notify: (eat 面包...)
notify: (eat 水果...)
Returning Types that Implement Traitspub trait Summary { fn summarize(&self) -> String; } pub struct NewsArticle { pub headline: String, pub location: String, pub author: String, pub content: String, } impl Summary for NewsArticle { fn summarize(&self) -> String { format!("{}, by {} ({})", self.headline, self.author, self.location) } } pub struct Tweet { pub username: String, pub content: String, pub reply: bool, pub retweet: bool, } impl Summary for Tweet { fn summarize(&self) -> String { format!("{}: {}", self.username, self.content) } } fn returns_summarizable() -> impl Summary { Tweet { username: String::from("horse_ebooks"), content: String::from( "of course, as you probably already know, people", ), reply: false, retweet: false, } }
泛型的复制与比较#![allow(unused)] fn largest<T: PartialOrd + Copy>(list: &[T]) -> T { let mut largest = list[0]; for &item in list { if item > largest { largest = item; } } largest } pub fn test() { let number_list = vec![34, 50, 25, 100, 65]; let result = largest(&number_list); println!("The largest number is {}", result); let char_list = vec!['y', 'm', 'a', 'q']; let result = largest(&char_list); println!("The largest char is {}", result); } If we don’t want to restrict the
Validating References with Lifetimes说生命周期就绕不开rust的引用与借用,可先阅读一遍下面的文章,回顾一下引用与借用的概念,再继续阅读本文章 2.5 References & BorrowingOne detail we didn’t discuss in the “References and Borrowing” section in Chapter 4 is that every reference in Rust has a lifetime, which is the scope for which that reference is valid. Most of the time, lifetimes are implicit and inferred, just like most of the time, types are inferred. We must annotate types when multiple types are possible. In a similar way, we must annotate lifetimes when the lifetimes of references could be related in a few different ways. Rust requires us to annotate the relationships using generic lifetime parameters to ensure the actual references used at runtime will definitely be valid.
Preventing Dangling References with Lifetimesfn main() { { let r; { let x = 5; r = &x; } println!("r: {}", r); } } Note: The examples declare variables without giving them an initial value, so the variable name exists in the outer scope. At first glance, this might appear to be in conflict with Rust’s having no null values. However, if we try to use a variable before giving it a value, we’ll get a compile-time error, which shows that Rust indeed does not allow null values. The outer scope declares a variable named $ cargo run Compiling chapter10 v0.1.0 (file:///projects/chapter10) error[E0597]: `x` does not live long enough --> src/main.rs:7:17 | 7 | r = &x; | ^^ borrowed value does not live long enough 8 | } | - `x` dropped here while still borrowed 9 | 10 | println!("r: {}", r); | - borrow later used here error: aborting due to previous error For more information about this error, try `rustc --explain E0597`. error: could not compile `chapter10`. To learn more, run the command again with --verbose. The variable
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论