Rust - 泛型
Rust - 泛型与特性
Section titled “Rust - 泛型与特性”泛型是 Rust 最强大的特性之一。它们允许你编写可处理多种不同数据类型的抽象、可重用代码。这减少了代码重复并提高了类型安全性,所有这些都不会带来任何运行时性能开销——这一原则被称为零成本抽象。
我们已经在 Vec<T>、Option<T> 和 Result<T, E> 等类型中看到了泛型的实际应用。其中的 <T> 是一个类型参数,是具体类型的占位符,将在使用泛型代码时指定。
你可以定义使用泛型类型参数的结构体。这对于创建可以存储任何类型值的容器或数据结构非常有用。
// 一个泛型 Point 结构体,可以为 x 和 y 存储任意两种类型。struct Point<T, U> { x: T, y: U,}
fn main() { // 一个 x 和 y 都是整数的实例。 let integer_point = Point { x: 5, y: 10 }; println!("Integer point: x = {}, y = {}", integer_point.x, integer_point.y);
// 一个 x 是浮点数、y 是字符的实例。 let mixed_point = Point { x: 1.0, y: 'c' }; println!("Mixed point: x = {}, y = {}", mixed_point.x, mixed_point.y);}我们还可以编写作用于泛型类型的函数。为此,我们需要告诉编译器泛型类型 T 必须具备哪些能力。我们通过使用特性约束来实现这一点。
例如,如果我们要编写一个打印值的函数,类型 T 必须实现 Display 特性。语法 <T: Display> 将泛型类型 T 约束为只能是可显示的类型。
use std::fmt::Display;
// 这个函数接受一个泛型类型 `T`,它必须实现 `Display` 特性。fn print_item<T: Display>(item: T) { println!("Here is your item: {}", item);}
fn main() { print_item(10_u32); // 适用于 u32 print_item("Hello, Generics!"); // 适用于 &str print_item(3.14); // 适用于 f64}特性:定义共享行为
Section titled “特性:定义共享行为”一个特性定义了一组类型必须实现的方法。它类似于其他语言中的接口。特性是我们在 Rust 中实现抽象和多态的方式。它们允许不同类型共享相同的行为。
让我们定义一个 Summary 特性,它提供对象数据的摘要。
// 1. 定义特性pub trait Summary { // 一个抽象方法;实现该特性的类型必须提供其方法体。 fn summarize_author(&self) -> String;
// 一个默认方法;实现该特性的类型可以使用或覆盖它。 fn summarize(&self) -> String { format!("(Read more from {}...)", self.summarize_author()) }}
// 2. 定义我们的结构体pub struct NewsArticle { pub headline: String, pub author: String,}
pub struct Tweet { pub username: String, pub content: String,}
// 3. 为我们的结构体实现特性impl Summary for NewsArticle { fn summarize_author(&self) -> String { format!("@{}", self.author) }}
impl Summary for Tweet { fn summarize_author(&self) -> String { format!("@{}", self.username) }
// 我们也可以覆盖默认方法 fn summarize(&self) -> String { format!("{}: {}", self.username, self.content) }}
// 4. 使用特性fn main() { let tweet = Tweet { username: String::from("rustacean"), content: String::from("I love traits!"), };
let article = NewsArticle { headline: String::from("Rust 1.70 Released!"), author: String::from("The Rust Team"), };
println!("New tweet: {}", tweet.summarize()); println!("New article: {}", article.summarize());}derive 宏
Section titled “derive 宏”对于标准库中许多常见的特性(例如用于打印的 Debug、用于复制的 Clone、用于比较的 PartialEq),你无需手动编写实现。Rust 提供了 #[derive] 属性来为你自动生成实现。这极大地节省了时间,也是 Rust 中非常常见的做法。
// 为此结构体自动实现 Debug、Clone 和 PartialEq。#[derive(Debug, Clone, PartialEq)]struct Rectangle { width: u32, height: u32,}
fn main() { let r1 = Rectangle { width: 30, height: 50 }; let r2 = r1.clone(); // 我们可以克隆它,因为有 `#[derive(Clone)]`
// 我们可以使用 `{:?}` 打印它,因为有 `#[derive(Debug)]` println!("Rectangle 1: {:?}", r1);
// 我们可以比较它们,因为有 `#[derive(PartialEq)]` println!("Are they equal? {}", r1 == r2);}