- 通过将代码提取为函数来减少重复工作
- 泛型数据类型
- 在函数定义中
- 在结构体定义中
- 在枚举定义中
- 在方法定义中
- 泛型代码的性能问题
- trait: 定义共享行为
- 定义trait
- 为类型实现trait
- 默认实现
- 使用trait作为参数
- trait约束
- 通过+语法来指定多个trait约束
- 使用where从句来简化trait约束
- 返回实现了trait的类型
- 使用trait约束来修复largest函数
- 使用trait约束来有条件地实现方法
- 使用生命周期保证引用的有效性
- 使用生命周期来避免悬垂引用
- 借用检查器
- 函数中的泛型生命周期
- 生命周期标注语法
- 函数签名中的生命周期标注
- 深入理解生命周期
- 结构体定义中的生命周期标注
- 生命周期省略
- 方法定义中的生命周期标注
- 静态生命周期
- 同时使用泛型参数、trait约束与生命周期
编译器采用三条规则来判断引用何时不需要明确的注解。第一条规则适用于输入生命周期,后两条规则适用于输出生命周期。如果编译器检查完这三条规则后仍然存在没有计算出生命周期的引用,编译器将会停止并生成错误。这些规则适用于 fn 定义,以及 impl 块。
第一条规则是每一个是引用的参数都有它自己的生命周期参数。换句话说就是,有一个引用参数的函数有一个生命周期参数:fn foo<'a>(x: &'a i32),有两个引用参数的函数有两个不同的生命周期参数,fn foo<'a, 'b>(x: &'a i32, y: &'b i32),依此类推。
第二条规则是如果只有一个输入生命周期参数,那么它被赋予所有输出生命周期参数:fn foo<'a>(x: &'a i32) -> &'a i32。
第三条规则是如果方法有多个输入生命周期参数并且其中一个参数是 &self 或 &mut self,说明是个对象的方法(method), 那么所有输出生命周期参数被赋予 self 的生命周期。第三条规则使得方法更容易读写,因为只需更少的符号。
use std::cmp::PartialOrd;
use std::fmt::Display;
fn largest_i32(list: &[i32]) -> i32 {
let mut largest = list[0];
for &item in list.iter() {
if item > largest {
largest = item;
}
}
largest
}
fn largest_char(list: &[char]) -> char {
let mut largest = list[0];
for &item in list.iter() {
if item > largest {
largest = item;
}
}
largest
}
/*
* fn largest<T>(list: &[T]) -> T {
* let mut largest = list[0];
* for &item in list.iter() {
* if item > largest {
* largest = item;
* }
* }
* largest;
* }
*/
struct Point<T, U> {
x: T,
y: U,
}
impl<T, U> Point<T, U> {
fn x(&self) -> &T {
&self.x
}
fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W> {
Point {
x: self.x,
y: other.y,
}
}
}
impl Point<f32, f32> {
fn distance_from_origin(&self) -> f32 {
(self.x.powi(2) + self.y.powi(2)).sqrt()
}
}
pub trait Summary {
fn summarize_author(&self) -> String;
fn summarize_1(&self) -> String;
fn summarize_2(&self) -> String {
format!("(Read more from {}...)", self.summarize_author())
}
}
pub struct NewsArticle {
pub headline: String,
pub location: String,
pub author: String,
pub content: String,
}
impl Summary for NewsArticle {
fn summarize_1(&self) -> String {
format!("{}, by {} ({})",self.headline, self.author, self.location)
}
fn summarize_author(&self) -> String {
format!("{}", self.author)
}
}
pub struct Tweet {
pub username: String,
pub content: String,
pub reply: bool,
pub retweet: bool,
}
impl Summary for Tweet {
fn summarize_1(&self) -> String {
format!("{}: {}",self.username, self.content)
}
fn summarize_author(&self) -> String {
format!("@{}", self.username)
}
}
pub fn notify(item: impl Summary) {
println!("Breaking news! {}", item.summarize_2());
}
/*
* pub fn notify<T: Summary>(item: T) {
* println!("Breaking news! {}", item.summarize());
* }
*
* pub fn notify(item1: impl Summary, item2: impl Summary) {...}
*
* pub fn notify<T:Summary>(item1: T, item2: T) {...}
*/
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,
}
}
/*
* fn some_function<T: Display + Clone, U: Clone + Debug>(t: T, u: U)
* -> i32 {}
*
* fn some_function<T, U>(t: T, u: U) -> i32
* where T: Display + Clone,
* U: Clong + Debug
*{}
*/
fn returns_summarizable_2() -> impl Summary {
Tweet {
username: String::from("horse_ebooks"),
content: String::from("of course, as you probably already know, people"),
reply: false,
retweet: false,
}
}
/*
* fn returns_summarizable(switch: bool) -> impl Summary {
* if switch {
* NewsArticle {
* headline: String::from("Penguins win the stanley Cup Championship!"),
* location: String::from("Pittsburgh, PA, USA"),
* author: String::from("Iceburgh"),
* content: String::from("The pittsburgh Penguins once again are the best\
* hocky team in the NHL."),
* }
* } else {
* Tweet {
* username: String::from("horse_ebooks"),
* content: String::from("of course, as you probably already know, people"),
* reply: false,
* retweet: false,
* }
* }
* }
*/
fn largest<T: PartialOrd + Copy>(list: &[T]) ->T {
let mut largest = list[0];
for &item in list.iter() {
if item > largest {
largest = item;
}
}
largest
}
struct Pair<T> {
x: T,
y: T,
}
impl<T> Pair<T> {
fn new(x: T, y: T) -> Self {
Self {
x,
y,
}
}
}
impl<T: Display + PartialOrd> Pair<T> {
fn cmp_display(&self) {
if self.x >= self.y {
println!("The ,largest menber is x = {}", self.x);
} else {
println!("The largest member is y = {}", self.y);
}
}
}
fn longest<'a>(x: &'a str, y:&'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
struct ImportantExcerpt<'a> {
part: &'a str,
}
impl<'a> ImportantExcerpt<'a> {
fn level(&self) ->i32 {
3
}
fn announce_and_return_part(&self, annoucement: &str) -> &str {
println!("Attention please: {}", annoucement);
self.part
}
}
fn longest_with_an_announcement<'a, T>(x: &'a str, y: &'a str, ann: T) -> &'a str
where T: Display
{
println!("Announcement! {}", ann);
if x.len() > y.len() {
x
} else {
y
}
}
fn main() {
let number_list = vec![34, 50, 25, 100, 65];
let result = largest_i32(&number_list);
println!("The largest number is {}", result);
let char_list = vec!['y', 'm', 'a', 'q'];
let result = largest_char(&char_list);
println!("The largest char is {}", result);
let integer = Point{ x: 5, y: 10 };
let float = Point{ x: 1.0, y: 4.0 };
let wont_work = Point{ x: 5, y: 4.0 };
let p1 = Point{ x: 5, y: 10.4 };
let p2 = Point{ x: "Hello", y: 'c' };
let p3 = p1.mixup(p2);
println!("p3.x = {}, p3.y = {}", p3.x, p3.y);
let tweet = Tweet {
username: String::from("horse_ebooks"),
content: String::from("of course, as you probably already know, people"),
reply: false,
retweet: false,
};
println!("1 new tweet: {}", tweet.summarize_1());
let article = NewsArticle {
headline: String::from("Penguins win the Stanley cup Championship!"),
location: String::from("Pittsburgh, PA, USA"),
author: String::from("Iceburgh"),
content: String::from("The pittsburgh Penguins once again are the best \
hockey team in the NHL."),
};
println!("New article available! {}", article.summarize_2());
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);
let r;
{
let x = 5;
r = &x;
}
//println!("r: {}", r);
let string1 = String::from("abcd");
let string2 = "xyz";
let result = longest(string1.as_str(), string2);
println!("The longest string is {}", result);
let string1 = String::from("long string is long");
{
let string2 = String::from("xyz");
let result = longest(string1.as_str(), string2.as_str());
println!("The longest string is {}", result);
}
let novel = String::from("Call me Ishmael. Some years ago...");
let first_sentence = novel.split('.')
.next().expect("Could not find a '.'");
let i = ImportantExcerpt { part: first_sentence };
let s: &'static str = "I hava a static lifetime.";
}
版权声明:本文为weixin_50475073原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。