深入浅出Rust:泛型、Trait与生命周期的硬核指南在Rust编程的世界中,泛型、Trait和生命周期是构建高效、可复用代码的三大核心支柱。它们不仅让你的代码更简洁优雅,还能确保内存安全和性能优化。无论是消除重复代码,还是定义灵活的接口,亦或是管理引用的生命周期,掌握这三者将让你在Rust开发中
在Rust编程的世界中,泛型、Trait和生命周期是构建高效、可复用代码的三大核心支柱。它们不仅让你的代码更简洁优雅,还能确保内存安全和性能优化。无论是消除重复代码,还是定义灵活的接口,亦或是管理引用的生命周期,掌握这三者将让你在Rust开发中如虎添翼。本文将带你从基础到进阶,结合代码实例,轻松解锁Rust的这些“黑科技”!
本文深入探讨了Rust编程中的泛型、Trait和生命周期三大核心概念。从消除代码重复的函数提取开始,逐步介绍如何利用泛型提高代码复用性,通过Trait定义共享行为,以及借助生命周期管理引用以避免悬垂引用等问题。文章结合清晰的代码示例,涵盖泛型在函数、结构体和枚举中的应用,Trait的定义与实现,以及生命周期的标注规则和实际场景。无论你是Rust新手还是进阶开发者,这篇文章都将为你提供实用的知识和技巧,助你写出更安全、更高效的Rust代码。
fn main() {
let number_list = vec![34, 50, 25, 100, 65];
let mut largest = number_list[0];
for number in number_list {
if number > largest {
largest = number;
}
}
println!("The largest number is {}", largest);
}
fn largest(list: &[i32]) -> i32 {
let mut largest = list[0];
for &item in list { // &item 解构
if item > largest {
largest = item;
}
}
largest
}
fn main() {
let number_list = vec![34, 50, 25, 100, 65];
let result = largest(&number_list);
println!("The largest number is {}", result);
let number_list = vec![102, 34, 6000, 89, 54, 2, 43, 8];
let result = largest(&number_list);
println!("The largest number is {}", result);
}
fn largest<T>(list: &[T]) -> T {...}
fn largest<T>(list: &[T]) -> T {
let mut largest = list[0];
for &item in list {
if item > largest { // 比较 报错 ToDo
largest = item;
}
}
largest
}
fn main() {
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 number is {}", result);
}
struct Point<T> {
x: T,
y: T,
}
struct Point1<T, U> {
x: T,
y: U,
}
fn main() {
let integer = Point {x: 5, y: 10};
let float = Point(x: 1.0, y: 4.0);
let integer1 = Point1 {x: 5, y: 10.0};
}
Option<T>
,Result<T, E>
enum Option<T> {
Some(T),
None,
}
enum Result<T, E> {
Ok(T),
Err(E),
}
fn main() {}
struct Point<T> {
x: T,
y: T,
}
impl<T> Point<T> {
fn x(&self) -> &T {
&self.x
}
}
impl Point<i32> {
fn x1(&self) -> &i32 {
&self.x
}
}
fn main() {
let p = Point {x: 5, y: 10};
println!("p.x = {}", p.x());
}
impl<T> Point<T>
impl Point<f32>
struct Point<T, U> {
x: T,
y: U,
}
impl<T, U> Point<T, U> {
fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W> {
Point {
x: self.x,
y: other.y,
}
}
}
fn main() {
let p1 = Point {x: 5, y: 4};
let p2 = Point {x: "Hello", y: 'c'};
let p3 = p1.mixup(p2);
println!("p3.x = {}, p3.y = {}", p3.x, p3.y);
}
fn main() {
let integer = Some(5);
let float = Some(5.0);
}
enum Option_i32 {
Some(i32),
None,
}
enum Option_f64 {
Some(f64),
None,
}
fn main() {
let integer = Option_i32::Some(5);
let float = Option_f64::Some(5.0);
}
pub trait Summary {
fn summarize(&self) -> String;
}
// NewsArticle
// Tweet
fn main() {}
impl xxxx for Tweet {...}
lib.rs 文件
pub 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)
}
}
main.rs 文件
use demo::Summary;
use demo::Tweet;
fn main() {
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())
}
lib.rs 文件
pub trait Summary {
// fn summarize(&self) -> String;
fn summarize(&self) -> String {
String::from("(Read more...)")
}
}
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)
}
}
main.rs 文件
use demo::NewsArticle;
use demo::Summary;
fn main() {
let article = NewsArticle {
headline: String::from("Penguins win the Stanley Cup Championship!"),
content: String::from("The pittsburgh penguins once again are the best hockey team in the NHL."),
author: String::from("Iceburgh"),
location: String::from("Pittsburgh, PA, USA"),
};
println!("1 new tweet: {}", article .summarize())
}
pub trait Summary {
fn summarize_author(&self) -> String;
fn summarize(&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_author(&self) -> String {
format!("@{}", self.author)
}
}
pub fn notify(item: impl Summary) {
println!("Breaking news! {}", item.summarize());
}
pub fn notify<T: Summary>(item: T) {
println!("Breaking news! {}", item.summarize());
}
pub fn notify(item: impl Summary + Display) {
println!("Breaking news! {}", item.summarize());
}
pub fn notify<T: Summary + Display>(item: T) {
println!("Breaking news! {}", item.summarize());
}
pub fn notify<T: Summary + Display, U: Clone + Debug>(a: T, b: U) -> String {
format!("Breaking news! {}", a.summarize())
}
pub fn notify<T, U>(a: T, b: U) -> String
where
T: Summary + Display,
U: Clone + Debug,
{
format!("Breaking news! {}", a.summarize())
}
pub fn notify1(s: &str) -> impl Summary {
NewsArticle {
headline: String::from("Penguins win the Stanley Cup Championship!"),
content: String::from("The Pittsburgh Penguins once again are the best hockey team in the NHL."),
author: String::from("Iceburgh"),
location: String::from("Pittsburgh, PA, USA"),
}
}
fn largest<T: PartialOrd + Clone>(list: &[T]) -> T {
let mut largest = list[0].clone();
for item in list.iter() {
if item > &largest { // std::cmp::ParticalOrd
largest = item.clone();
}
}
largest
}
fn main() {
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)
}
fn largest<T: PartialOrd + Clone>(list: &[T]) -> &T {
let mut largest = &list[0];
for item in list.iter() {
if item > &largest { // std::cmp::ParticalOrd
largest = item;
}
}
largest
}
fn main() {
let str_list = vec![String::from("hello"), String::from("world")];
let result = largest(&str_list);
println!("The largest word is {}", result);
}
use std::fmt::Display;
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 member is x = {}", self.x);
} else {
println!("The largest member is y = {}", self.y);
}
}
}
fn main() {
let s = 3.to_string();
}
fn main() {
{
let r;
{
let x = 5;
r = &x; // 报错
}
println!("r: {}", r);
}
}
fn main() {
let x = 5;
let r = &x;
println!("r: {}", r);
}
fn main() {
let string1 = String::from("abcd");
let string2 = "xyz";
let result = longest(string1.as_str(), string2);
println!("The longest string is {}", result);
}
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
fn main() {
let string1 = String::from("abcd");
let result;
{
let string2 = String::from("xyz");
let result = longest(string1.as_str(), string2.as_str()); // 报错 string2
}
println!("The longest string is {}", result);
}
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
fn main() {
let string1 = String::from("abcd");
let string2 = "xyz";
let result = longest(string1.as_str(), string2);
println!("The longest string is {}", result);
}
fn longest<'a>(x: &'a str, y: &str) -> &'a str {
x
}
fn main() {
let string1 = String::from("abcd");
let string2 = "xyz";
let result = longest(string1.as_str(), string2);
println!("The longest string is {}", result);
}
fn longest<'a>(x: &'a str, y: &str) -> &'a str {
let result = String::from("abc");
result.as_str() // 报错
}
fn longest<'a>(x: &'a str, y: &str) -> String {
let result = String::from("abc");
result
}
struct ImportantExcerpt<'a> {
part: &'a str,
}
fn main() {
let novel = String::from("Call me Ishmael. Some years ago ...")
let first_sentence = novel.split('.')
.next()
.expect("Could not found a '.'");
let i = ImportantExcerpt {
part: first_sentence
};
}
fn first_word(s: &str) -> &str {
fn first_word<'a>(s: &'a str) -> &str {
fn first_word<'a>(s: &'a str) -> &'a str {
fn longest(x: &str, y: &str) -> &str{
fn longest<'a, 'b>(x: &'a str, y: &'b str) -> &str{
// 报错struct ImportantExcerpt<'a> {
part: &'a str,
}
impl<'a> ImportantExcerpt<'a> {
fn level(&self) -> i32 {
3
}
fn snnounce_and_return_part(&self, announcement: &str) -> &str {
println!("Attention please: {}", announcement);
self.part
}
}
fn main() {
let novel = String::from("Call me Ishmael. Some years ago ...")
let first_sentence = novel.split('.')
.next()
.expect("Could not found a '.'");
let i = ImportantExcerpt {
part: first_sentence,
};
}
let s: &'static str = "I have a static lifetime.";
use std::fmt::Display;
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() {}
泛型、Trait和生命周期是Rust编程中不可或缺的工具,它们共同构成了Rust代码安全性和灵活性的基石。通过泛型,我们可以编写高度复用的代码;通过Trait,我们可以定义类型间的共享行为;通过生命周期,我们确保引用的正确性和内存安全。本文从实际代码出发,带你一步步掌握这些概念的应用场景和实现方法。希望你能将这些知识融入到自己的Rust项目中,写出更优雅、更高效的代码!快动手实践吧,Rust的魅力等待你去探索!
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!