从Python到Rust - 3
第7章:特征与泛型
7.1 特征 (Traits) 概述
特征(Trait)是Rust实现多态的核心机制,类似于其他语言中的接口或协议。对于Python开发者来说,Trait最接近于抽象基类(ABC)和协议(Protocol)的概念。
Python协议和抽象基类
# Python抽象基类
from abc import ABC, abstractmethod
from typing import Protocol
class Drawable(ABC):
@abstractmethod
def draw(self) -> None:
pass
class Shape(Drawable):
def __init__(self, name: str):
self.name = name
def draw(self) -> None:
print(f"Drawing {self.name}")
# Python协议(类型提示)
class SupportsDraw(Protocol):
def draw(self) -> None: ...
def render_shape(shape: SupportsDraw) -> None:
shape.draw()
Rust特征
// Rust特征定义
trait Drawable {
fn draw(&self);
}
struct Circle {
radius: f64,
}
struct Rectangle {
width: f64,
height: f64,
}
// 为类型实现特征
impl Drawable for Circle {
fn draw(&self) {
println!("Drawing a circle with radius {}", self.radius);
}
}
impl Drawable for Rectangle {
fn draw(&self) {
println!("Drawing a rectangle {}x{}", self.width, self.height);
}
}
// 使用特征作为参数
fn render_shape(shape: &dyn Drawable) {
shape.draw();
}
fn main() {
let circle = Circle { radius: 5.0 };
let rectangle = Rectangle { width: 10.0, height: 20.0 };
render_shape(&circle);
render_shape(&rectangle);
}
7.2 特征的基本用法
定义和实现特征
// 定义特征
trait Summary {
fn summarize(&self) -> String;
// 默认实现
fn summarize_author(&self) -> String {
String::from("(Read more...)")
}
}
struct NewsArticle {
headline: String,
location: String,
author: String,
content: String,
}
struct Tweet {
username: String,
content: String,
reply: bool,
retweet: bool,
}
// 实现特征
impl Summary for NewsArticle {
fn summarize(&self) -> String {
format!("{}, by {} ({})", self.headline, self.author, self.location)
}
// 重写默认实现
fn summarize_author(&self) -> String {
format!("@{}", self.author)
}
}
impl Summary for Tweet {
fn summarize(&self) -> String {
format!("{}: {}", self.username, self.content)
}
}
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());
println!("Author: {}", tweet.summarize_author()); // 使用默认实现
}
# Python等价实现
from abc import ABC, abstractmethod
class Summary(ABC):
@abstractmethod
def summarize(self) -> str:
pass
# 默认实现
def summarize_author(self) -> str:
return "(Read more...)"
class NewsArticle(Summary):
def __init__(self, headline: str, location: str, author: str, content: str):
self.headline = headline
self.location = location
self.author = author
self.content = content
def summarize(self) -> str:
return f"{self.headline}, by {self.author} ({self.location})"
# 重写默认实现
def summarize_author(self) -> str:
return f"@{self.author}"
class Tweet(Summary):
def __init__(self, username: str, content: str, reply: bool, retweet: bool):
self.username = username
self.content = content
self.reply = reply
self.retweet = retweet
def summarize(self) -> str:
return f"{self.username}: {self.content}"
def main():
tweet = Tweet(
username="horse_ebooks",
content="of course, as you probably already know, people",
reply=False,
retweet=False
)
print(f"1 new tweet: {tweet.summarize()}")
print(f"Author: {tweet.summarize_author()}") # 使用默认实现
if __name__ == "__main__":
main()
7.3 特征作为参数
特征绑定
// 特征作为参数的不同方式
trait Display {
fn display(&self) -> String;
}
struct User {
name: String,
age: u32,
}
impl Display for User {
fn display(&self) -> String {
format!("{} (age: {})", self.name, self.age)
}
}
// 方式1:impl Trait语法
fn print_display(item: &impl Display) {
println!("{}", item.display());
}
// 方式2:特征绑定语法
fn print_display_verbose<T: Display>(item: &T) {
println!("{}", item.display());
}
// 方式3:where子句(用于复杂绑定)
fn print_display_where<T>(item: &T)
where
T: Display,
{
println!("{}", item.display());
}
// 多个特征绑定
fn print_and_clone<T>(item: &T)
where
T: Display + Clone,
{
println!("{}", item.display());
let _cloned = item.clone();
}
fn main() {
let user = User {
name: String::from("Alice"),
age: 30,
};
print_display(&user);
print_display_verbose(&user);
print_display_where(&user);
}
# Python类型提示和协议
from typing import Protocol, TypeVar
from abc import ABC, abstractmethod
class Display(Protocol):
def display(self) -> str: ...
class User:
def __init__(self, name: str, age: int):
self.name = name
self.age = age
def display(self) -> str:
return f"{self.name} (age: {self.age})"
# 方式1:直接使用协议
def print_display(item: Display) -> None:
print(item.display())
# 方式2:泛型类型变量
T = TypeVar('T', bound=Display)
def print_display_generic(item: T) -> None:
print(item.display())
# Python没有直接的多重约束语法,需要组合使用
from typing import Union
class Cloneable(Protocol):
def clone(self): ...
def print_and_clone(item: Display) -> None:
print(item.display())
# Python中需要检查是否有clone方法
if hasattr(item, 'clone'):
item.clone()
def main():
user = User("Alice", 30)
print_display(user)
print_display_generic(user)
print_and_clone(user)
if __name__ == "__main__":
main()
7.4 返回实现特征的类型
返回impl Trait
// 返回实现特征的类型
trait Animal {
fn make_sound(&self) -> String;
}
struct Dog {
name: String,
}
struct Cat {
name: String,
}
impl Animal for Dog {
fn make_sound(&self) -> String {
format!("{} says Woof!", self.name)
}
}
impl Animal for Cat {
fn make_sound(&self) -> String {
format!("{} says Meow!", self.name)
}
}
// 返回impl Trait(只能返回同一种具体类型)
fn get_dog() -> impl Animal {
Dog {
name: String::from("Buddy"),
}
}
// 如果需要返回不同类型,需要使用Box<dyn Trait>
fn get_animal(is_dog: bool) -> Box<dyn Animal> {
if is_dog {
Box::new(Dog {
name: String::from("Buddy"),
})
} else {
Box::new(Cat {
name: String::from("Whiskers"),
})
}
}
fn main() {
let dog = get_dog();
println!("{}", dog.make_sound());
let animal1 = get_animal(true);
let animal2 = get_animal(false);
println!("{}", animal1.make_sound());
println!("{}", animal2.make_sound());
}
# Python返回协议类型
from typing import Protocol
from abc import ABC, abstractmethod
class Animal(Protocol):
def make_sound(self) -> str: ...
class Dog:
def __init__(self, name: str):
self.name = name
def make_sound(self) -> str:
return f"{self.name} says Woof!"
class Cat:
def __init__(self, name: str):
self.name = name
def make_sound(self) -> str:
return f"{self.name} says Meow!"
# Python可以轻松返回不同的具体类型
def get_dog() -> Animal:
return Dog("Buddy")
def get_animal(is_dog: bool) -> Animal:
if is_dog:
return Dog("Buddy")
else:
return Cat("Whiskers")
def main():
dog = get_dog()
print(dog.make_sound())
animal1 = get_animal(True)
animal2 = get_animal(False)
print(animal1.make_sound())
print(animal2.make_sound())
if __name__ == "__main__":
main()
7.5 泛型 (Generics)
泛型函数
// 泛型函数
fn largest<T: PartialOrd + Copy>(list: &[T]) -> T {
let mut largest = list[0];
for &item in list {
if item > largest {
largest = item;
}
}
largest
}
// 多个泛型参数
fn compare_and_display<T, U>(t: &T, u: &U) -> String
where
T: std::fmt::Display + PartialOrd,
U: std::fmt::Display,
{
if *t > *t { // 这里有意写错来展示类型检查
format!("{} is greater", t)
} else {
format!("{} and {} are being compared", t, u)
}
}
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);
}
# Python泛型函数
from typing import TypeVar, List, Protocol
class Comparable(Protocol):
def __lt__(self, other) -> bool: ...
def __gt__(self, other) -> bool: ...
T = TypeVar('T', bound=Comparable)
def largest(lst: List[T]) -> T:
largest_item = lst[0]
for item in lst:
if item > largest_item:
largest_item = item
return largest_item
# 多个泛型参数
from typing import Any
T = TypeVar('T')
U = TypeVar('U')
def compare_and_display(t: T, u: U) -> str:
# Python的动态类型使得比较更灵活但不太安全
try:
if t > t: # 同样的错误
return f"{t} is greater"
else:
return f"{t} and {u} are being compared"
except TypeError:
return f"Cannot compare {t} and {u}"
def main():
number_list = [34, 50, 25, 100, 65]
result = largest(number_list)
print(f"The largest number is {result}")
char_list = ['y', 'm', 'a', 'q']
result = largest(char_list)
print(f"The largest char is {result}")
if __name__ == "__main__":
main()
泛型结构体
// 泛型结构体
struct Point<T> {
x: T,
y: T,
}
impl<T> Point<T> {
fn new(x: T, y: T) -> Self {
Point { x, y }
}
fn x(&self) -> &T {
&self.x
}
}
// 为特定类型实现方法
impl Point<f32> {
fn distance_from_origin(&self) -> f32 {
(self.x.powi(2) + self.y.powi(2)).sqrt()
}
}
// 多个泛型参数
struct Pair<T, U> {
first: T,
second: U,
}
impl<T, U> Pair<T, U> {
fn new(first: T, second: U) -> Self {
Pair { first, second }
}
fn get_first(&self) -> &T {
&self.first
}
fn get_second(&self) -> &U {
&self.second
}
}
fn main() {
let integer_point = Point::new(5, 10);
let float_point = Point::new(1.0, 4.0);
println!("integer_point.x = {}", integer_point.x());
println!("float_point distance = {}", float_point.distance_from_origin());
let pair = Pair::new("hello", 42);
println!("pair: {} - {}", pair.get_first(), pair.get_second());
}
# Python泛型类
from typing import TypeVar, Generic
T = TypeVar('T')
U = TypeVar('U')
class Point(Generic[T]):
def __init__(self, x: T, y: T):
self.x = x
self.y = y
def get_x(self) -> T:
return self.x
# Python没有特定类型的方法实现,需要用函数或检查类型
def distance_from_origin(point: Point[float]) -> float:
import math
return math.sqrt(point.x**2 + point.y**2)
class Pair(Generic[T, U]):
def __init__(self, first: T, second: U):
self.first = first
self.second = second
def get_first(self) -> T:
return self.first
def get_second(self) -> U:
return self.second
def main():
integer_point = Point(5, 10)
float_point = Point(1.0, 4.0)
print(f"integer_point.x = {integer_point.get_x()}")
print(f"float_point distance = {distance_from_origin(float_point)}")
pair = Pair("hello", 42)
print(f"pair: {pair.get_first()} - {pair.get_second()}")
if __name__ == "__main__":
main()
7.6 特征边界
使用特征边界限制泛型
// 特征边界示例
use std::fmt::Display;
// 简单特征边界
fn print_it<T: Display>(item: T) {
println!("Printing: {}", item);
}
// 多个特征边界
fn print_and_debug<T>(item: T)
where
T: Display + std::fmt::Debug + Clone,
{
println!("Display: {}", item);
println!("Debug: {:?}", item);
let _cloned = item.clone();
}
// 带有生命周期的特征边界
fn longest_with_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
}
}
// 为满足特征边界的类型实现功能
struct Wrapper<T>(T);
impl<T: Display> Display for Wrapper<T> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "Wrapped: {}", self.0)
}
}
fn main() {
print_it("Hello");
print_it(42);
let number = 5;
print_and_debug(number);
let string1 = "long string is long";
let string2 = "xyz";
let announcement = "Today is someone's birthday!";
let result = longest_with_announcement(string1, string2, announcement);
println!("The longest string is {}", result);
let wrapper = Wrapper("hello");
println!("{}", wrapper);
}
# Python类型约束
from typing import TypeVar, Protocol
from abc import ABC, abstractmethod
class Displayable(Protocol):
def __str__(self) -> str: ...
class Debuggable(Protocol):
def __repr__(self) -> str: ...
class Cloneable(Protocol):
def clone(self): ...
# Python中需要手动检查或使用多重继承
def print_it(item: Displayable) -> None:
print(f"Printing: {item}")
def print_and_debug(item) -> None: # Python中很难表达多重约束
print(f"Display: {item}")
print(f"Debug: {repr(item)}")
# 需要手动检查是否可克隆
if hasattr(item, 'clone') and callable(getattr(item, 'clone')):
item.clone()
def longest_with_announcement(x: str, y: str, ann: Displayable) -> str:
print(f"Announcement! {ann}")
if len(x) > len(y):
return x
else:
return y
# 包装器类
from typing import Generic
T = TypeVar('T')
class Wrapper(Generic[T]):
def __init__(self, value: T):
self.value = value
def __str__(self) -> str:
return f"Wrapped: {self.value}"
def main():
print_it("Hello")
print_it(42)
number = 5
print_and_debug(number)
string1 = "long string is long"
string2 = "xyz"
announcement = "Today is someone's birthday!"
result = longest_with_announcement(string1, string2, announcement)
print(f"The longest string is {result}")
wrapper = Wrapper("hello")
print(wrapper)
if __name__ == "__main__":
main()
7.7 关联类型
使用关联类型简化特征定义
// 使用关联类型
trait Iterator {
type Item; // 关联类型
fn next(&mut self) -> Option<Self::Item>;
}
struct Counter {
current: usize,
max: usize,
}
impl Counter {
fn new(max: usize) -> Counter {
Counter { current: 0, max }
}
}
impl Iterator for Counter {
type Item = usize; // 指定关联类型
fn next(&mut self) -> Option<Self::Item> {
if self.current < self.max {
let current = self.current;
self.current += 1;
Some(current)
} else {
None
}
}
}
// 对比:如果用泛型代替关联类型
trait IteratorGeneric<T> {
fn next(&mut self) -> Option<T>;
}
// 关联类型的优势:每个类型只能有一个Iterator实现
// 而泛型版本可以为同一类型实现多个IteratorGeneric<T>
fn main() {
let mut counter = Counter::new(3);
while let Some(num) = counter.next() {
println!("Counter: {}", num);
}
}
# Python中没有直接的关联类型概念,但可以用类型变量模拟
from typing import TypeVar, Generic, Optional, Iterator as PyIterator
T = TypeVar('T')
class Iterator(Generic[T]):
def next(self) -> Optional[T]:
raise NotImplementedError
class Counter(Iterator[int]): # 明确指定类型
def __init__(self, max_val: int):
self.current = 0
self.max = max_val
def next(self) -> Optional[int]:
if self.current < self.max:
current = self.current
self.current += 1
return current
else:
return None
# Python迭代器协议
def __iter__(self):
return self
def __next__(self):
result = self.next()
if result is None:
raise StopIteration
return result
def main():
counter = Counter(3)
# 使用自定义next方法
while True:
num = counter.next()
if num is None:
break
print(f"Counter: {num}")
# 或者使用Python的迭代器协议
counter2 = Counter(3)
for num in counter2:
print(f"Counter2: {num}")
if __name__ == "__main__":
main()
7.8 默认泛型类型参数和运算符重载
默认类型参数
// 默认泛型类型参数
use std::ops::Add;
#[derive(Debug, Copy, Clone, PartialEq)]
struct Point {
x: i32,
y: i32,
}
impl Add for Point {
type Output = Point; // 关联类型
fn add(self, other: Point) -> Point {
Point {
x: self.x + other.x,
y: self.y + other.y,
}
}
}
// Add trait的定义类似于:
// trait Add<Rhs = Self> { // Rhs有默认类型Self
// type Output;
// fn add(self, rhs: Rhs) -> Self::Output;
// }
// 使用不同的Rhs类型
struct Millimeters(u32);
struct Meters(u32);
impl Add<Meters> for Millimeters {
type Output = Millimeters;
fn add(self, other: Meters) -> Millimeters {
Millimeters(self.0 + (other.0 * 1000))
}
}
fn main() {
assert_eq!(
Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
Point { x: 3, y: 3 }
);
let mm = Millimeters(1000);
let m = Meters(1);
let result = mm + m;
println!("Result: {} mm", result.0);
}
# Python运算符重载
class Point:
def __init__(self, x: int, y: int):
self.x = x
self.y = y
def __add__(self, other: 'Point') -> 'Point':
return Point(self.x + other.x, self.y + other.y)
def __eq__(self, other: 'Point') -> bool:
return self.x == other.x and self.y == other.y
def __repr__(self) -> str:
return f"Point(x={self.x}, y={self.y})"
class Millimeters:
def __init__(self, value: int):
self.value = value
def __add__(self, other: 'Meters') -> 'Millimeters':
return Millimeters(self.value + other.value * 1000)
def __repr__(self) -> str:
return f"Millimeters({self.value})"
class Meters:
def __init__(self, value: int):
self.value = value
def __repr__(self) -> str:
return f"Meters({self.value})"
def main():
point1 = Point(1, 0)
point2 = Point(2, 3)
result = point1 + point2
assert result == Point(3, 3)
print(f"Point addition: {result}")
mm = Millimeters(1000)
m = Meters(1)
result = mm + m
print(f"Result: {result}")
if __name__ == "__main__":
main()
7.9 完全限定语法
歧义解析
// 完全限定语法用于解决方法名冲突
trait Pilot {
fn fly(&self);
}
trait Wizard {
fn fly(&self);
}
struct Human;
impl Pilot for Human {
fn fly(&self) {
println!("This is your captain speaking.");
}
}
impl Wizard for Human {
fn fly(&self) {
println!("Up!");
}
}
impl Human {
fn fly(&self) {
println!("*waving arms furiously*");
}
}
// 关联函数的歧义
trait Animal {
fn baby_name() -> String;
}
struct Dog;
impl Dog {
fn baby_name() -> String {
String::from("Spot")
}
}
impl Animal for Dog {
fn baby_name() -> String {
String::from("puppy")
}
}
fn main() {
let person = Human;
// 调用实例方法
person.fly(); // 调用Human的fly方法
Pilot::fly(&person); // 调用Pilot trait的fly方法
Wizard::fly(&person); // 调用Wizard trait的fly方法
// 调用关联函数
println!("A baby dog is called a {}", Dog::baby_name());
// 完全限定语法解决歧义
println!("A baby dog is called a {}", <Dog as Animal>::baby_name());
}
# Python中的方法解析
from abc import ABC, abstractmethod
class Pilot(ABC):
@abstractmethod
def fly(self) -> None:
pass
class Wizard(ABC):
@abstractmethod
def fly(self) -> None:
pass
class Human(Pilot, Wizard):
def fly(self) -> None:
print("*waving arms furiously*")
# Python使用不同的方法名避免冲突
def pilot_fly(self) -> None:
print("This is your captain speaking.")
def wizard_fly(self) -> None:
print("Up!")
# 类方法的处理
class Animal(ABC):
@classmethod
@abstractmethod
def baby_name(cls) -> str:
pass
class Dog(Animal):
@classmethod
def baby_name(cls) -> str:
return "puppy"
@classmethod
def dog_baby_name(cls) -> str:
return "Spot"
def main():
person = Human()
# Python的方法解析顺序(MRO)
person.fly() # 调用Human的fly方法
person.pilot_fly() # 手动调用pilot版本
person.wizard_fly() # 手动调用wizard版本
# 类方法调用
print(f"A baby dog is called a {Dog.dog_baby_name()}")
print(f"A baby dog is called a {Dog.baby_name()}")
if __name__ == "__main__":
main()
7.10 实践练习
练习1:构建一个通用的容器和迭代器
// Rust版本:通用容器
use std::fmt::Display;
trait Container<T> {
fn new() -> Self;
fn add(&mut self, item: T);
fn get(&self, index: usize) -> Option<&T>;
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
}
trait Printable {
fn print_all(&self);
}
struct MyVec<T> {
items: Vec<T>,
}
impl<T> Container<T> for MyVec<T> {
fn new() -> Self {
MyVec { items: Vec::new() }
}
fn add(&mut self, item: T) {
self.items.push(item);
}
fn get(&self, index: usize) -> Option<&T> {
self.items.get(index)
}
fn len(&self) -> usize {
self.items.len()
}
}
impl<T: Display> Printable for MyVec<T> {
fn print_all(&self) {
for (i, item) in self.items.iter().enumerate() {
println!("Item {}: {}", i, item);
}
}
}
// 自定义迭代器
impl<T> IntoIterator for MyVec<T> {
type Item = T;
type IntoIter = std::vec::IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
self.items.into_iter()
}
}
fn process_container<C, T>(mut container: C)
where
C: Container<T> + Printable,
T: Display + Clone,
{
container.add("Hello".to_string());
container.add("World".to_string());
println!("Container has {} items", container.len());
container.print_all();
}
fn main() {
let mut my_vec: MyVec<String> = Container::new();
my_vec.add("Rust".to_string());
my_vec.add("Programming".to_string());
println!("Length: {}", my_vec.len());
my_vec.print_all();
if let Some(item) = my_vec.get(0) {
println!("First item: {}", item);
}
// 测试迭代器
let my_vec2: MyVec<i32> = {
let mut vec = MyVec::new();
vec.add(1);
vec.add(2);
vec.add(3);
vec
};
for item in my_vec2 {
println!("Iterating: {}", item);
}
}
# Python版本:通用容器
from typing import TypeVar, Generic, Optional, Protocol, Iterator
from abc import ABC, abstractmethod
T = TypeVar('T')
class Container(Generic[T], ABC):
@abstractmethod
def add(self, item: T) -> None:
pass
@abstractmethod
def get(self, index: int) -> Optional[T]:
pass
@abstractmethod
def __len__(self) -> int:
pass
def is_empty(self) -> bool:
return len(self) == 0
class Printable(Protocol):
def print_all(self) -> None: ...
class MyList(Container[T]):
def __init__(self):
self.items: list[T] = []
def add(self, item: T) -> None:
self.items.append(item)
def get(self, index: int) -> Optional[T]:
if 0 <= index < len(self.items):
return self.items[index]
return None
def __len__(self) -> int:
return len(self.items)
def print_all(self) -> None:
for i, item in enumerate(self.items):
print(f"Item {i}: {item}")
# Python迭代器协议
def __iter__(self) -> Iterator[T]:
return iter(self.items)
def process_container(container: Container[str]) -> None:
container.add("Hello")
container.add("World")
print(f"Container has {len(container)} items")
if hasattr(container, 'print_all'):
container.print_all()
def main():
my_list: MyList[str] = MyList()
my_list.add("Rust")
my_list.add("Programming")
print(f"Length: {len(my_list)}")
my_list.print_all()
first_item = my_list.get(0)
if first_item:
print(f"First item: {first_item}")
# 测试迭代器
my_list2: MyList[int] = MyList()
my_list2.add(1)
my_list2.add(2)
my_list2.add(3)
for item in my_list2:
print(f"Iterating: {item}")
if __name__ == "__main__":
main()
练习2:构建一个类型安全的计算器
// Rust版本:类型安全计算器
use std::ops::{Add, Sub, Mul, Div};
use std::fmt::Display;
trait Number: Add<Output = Self> + Sub<Output = Self> + Mul<Output = Self> + Div<Output = Self>
+ Copy + PartialOrd + Display
where
Self: Sized,
{
fn zero() -> Self;
fn one() -> Self;
}
impl Number for i32 {
fn zero() -> Self { 0 }
fn one() -> Self { 1 }
}
impl Number for f64 {
fn zero() -> Self { 0.0 }
fn one() -> Self { 1.0 }
}
struct Calculator<T: Number> {
value: T,
}
impl<T: Number> Calculator<T> {
fn new(value: T) -> Self {
Calculator { value }
}
fn add(self, other: T) -> Self {
Calculator { value: self.value + other }
}
fn subtract(self, other: T) -> Self {
Calculator { value: self.value - other }
}
fn multiply(self, other: T) -> Self {
Calculator { value: self.value * other }
}
fn divide(self, other: T) -> Self {
Calculator { value: self.value / other }
}
fn result(&self) -> T {
self.value
}
fn reset(&mut self) {
self.value = T::zero();
}
}
impl<T: Number> Display for Calculator<T> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "Calculator({})", self.value)
}
}
// 为Calculator实现运算符
impl<T: Number> Add<T> for Calculator<T> {
type Output = Calculator<T>;
fn add(self, rhs: T) -> Self::Output {
self.add(rhs)
}
}
fn main() {
let calc = Calculator::new(10)
.add(5)
.multiply(2)
.subtract(3);
println!("Integer calculation result: {}", calc.result());
println!("Calculator display: {}", calc);
let float_calc = Calculator::new(10.5)
.add(2.5)
.divide(2.0);
println!("Float calculation result: {}", float_calc.result());
// 使用运算符
let calc2 = Calculator::new(20) + 10;
println!("Using operator: {}", calc2.result());
}
# Python版本:类型安全计算器
from typing import TypeVar, Generic, Protocol
from abc import ABC, abstractmethod
class Number(Protocol):
def __add__(self, other): ...
def __sub__(self, other): ...
def __mul__(self, other): ...
def __truediv__(self, other): ...
def __lt__(self, other) -> bool: ...
def __str__(self) -> str: ...
T = TypeVar('T', bound=Number)
class Calculator(Generic[T]):
def __init__(self, value: T):
self.value = value
def add(self, other: T) -> 'Calculator[T]':
return Calculator(self.value + other)
def subtract(self, other: T) -> 'Calculator[T]':
return Calculator(self.value - other)
def multiply(self, other: T) -> 'Calculator[T]':
return Calculator(self.value * other)
def divide(self, other: T) -> 'Calculator[T]':
return Calculator(self.value / other)
def result(self) -> T:
return self.value
def reset(self, zero_value: T) -> None:
self.value = zero_value
def __str__(self) -> str:
return f"Calculator({self.value})"
# 运算符重载
def __add__(self, other: T) -> 'Calculator[T]':
return self.add(other)
def main():
# 链式调用(Python风格)
calc = (Calculator(10)
.add(5)
.multiply(2)
.subtract(3))
print(f"Integer calculation result: {calc.result()}")
print(f"Calculator display: {calc}")
float_calc = (Calculator(10.5)
.add(2.5)
.divide(2.0))
print(f"Float calculation result: {float_calc.result()}")
# 使用运算符
calc2 = Calculator(20) + 10
print(f"Using operator: {calc2.result()}")
if __name__ == "__main__":
main()
7.11 高级特征模式
超特征 (Supertraits)
// 超特征:一个特征依赖另一个特征
use std::fmt::Display;
trait OutlinePrint: Display {
fn outline_print(&self) {
let output = self.to_string();
let len = output.len();
println!("{}", "*".repeat(len + 4));
println!("*{}*", " ".repeat(len + 2));
println!("* {} *", output);
println!("*{}*", " ".repeat(len + 2));
println!("{}", "*".repeat(len + 4));
}
}
struct Point {
x: i32,
y: i32,
}
impl Display for Point {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "({}, {})", self.x, self.y)
}
}
impl OutlinePrint for Point {}
fn main() {
let point = Point { x: 1, y: 3 };
point.outline_print();
}
# Python中的继承和mixin
from abc import ABC, abstractmethod
class Display(ABC):
@abstractmethod
def __str__(self) -> str:
pass
class OutlinePrint(Display): # 继承Display确保有__str__方法
def outline_print(self) -> None:
output = str(self)
length = len(output)
print("*" * (length + 4))
print("*" + " " * (length + 2) + "*")
print(f"* {output} *")
print("*" + " " * (length + 2) + "*")
print("*" * (length + 4))
class Point(OutlinePrint):
def __init__(self, x: int, y: int):
self.x = x
self.y = y
def __str__(self) -> str:
return f"({self.x}, {self.y})"
def main():
point = Point(1, 3)
point.outline_print()
if __name__ == "__main__":
main()
7.12 本章小结
通过本章学习,你应该掌握:
- 特征基础:定义、实现和使用特征
- 特征作为参数:impl Trait、特征绑定、where子句
- 泛型:泛型函数、结构体和枚举
- 特征边界:限制泛型类型的能力
- 关联类型:简化特征定义,避免类型参数泛滥
- 高级特性:默认类型参数、完全限定语法、超特征
与Python的关键差异:
特性 | Rust | Python |
---|---|---|
接口定义 | Trait | ABC/Protocol |
泛型 | 编译时单态化 | 运行时类型检查 |
类型约束 | 特征边界,编译时检查 | 类型提示,可选检查 |
关联类型 | 明确的类型关联 | 需要手动指定泛型参数 |
方法冲突 | 完全限定语法 | 方法解析顺序(MRO) |
性能 | 零成本抽象 | 运行时多态开销 |
关键要点:
- 特征是Rust实现抽象和多态的核心机制
- 泛型提供类型安全的代码重用
- 特征边界确保泛型类型具有所需的能力
- 关联类型简化了复杂特征的定义
- 编译时检查保证类型安全和性能
下一章预告: 我们将深入学习Rust的内存管理与性能优化,了解Rust如何实现零成本抽象。
第8章:内存管理与性能
在前面的章节中,我们已经了解了Rust的所有权系统的基础概念。本章将深入探讨Rust的内存管理机制,并与Python进行详细对比,帮助你理解为什么Rust能够实现零成本抽象和高性能。
8.1 内存管理模型对比
Python的内存管理
Python使用垃圾回收器(Garbage Collector)进行自动内存管理:
# Python - 运行时内存管理
class Person:
def __init__(self, name):
self.name = name
def create_people():
people = []
for i in range(1000):
person = Person(f"Person {i}") # 在堆上分配
people.append(person)
return people # 返回时,局部变量超出作用域,但对象仍在堆上
people = create_people()
# GC会在适当时机回收不再使用的对象
del people # 显式删除引用,但实际回收时机由GC决定
Python的内存管理特点:
- 运行时回收:GC在运行时扫描和回收内存
- 引用计数 + 循环检测:CPython使用引用计数作为主要机制
- 性能开销:GC暂停、引用计数开销
- 内存碎片:可能产生内存碎片
Rust的内存管理
Rust使用所有权系统进行编译时内存管理:
// Rust - 编译时内存管理
struct Person {
name: String,
}
impl Person {
fn new(name: &str) -> Self {
Person {
name: name.to_string(),
}
}
}
fn create_people() -> Vec<Person> {
let mut people = Vec::new();
for i in 0..1000 {
let person = Person::new(&format!("Person {}", i));
people.push(person); // 所有权转移到Vec中
}
people // 返回Vec,所有权转移给调用者
} // 局部变量在此处自动销毁
fn main() {
let people = create_people();
// 使用people...
} // people在此处自动销毁,内存立即释放
Rust的内存管理特点:
- 编译时确定:内存分配和释放在编译时确定
- 零成本抽象:运行时无额外开销
- 确定性销毁:对象在离开作用域时立即销毁
- 无内存泄漏:编译器保证内存安全
8.2 栈与堆的使用策略
Python中的栈和堆
# Python - 大部分对象都在堆上
def stack_vs_heap():
# 这些看起来像"栈上"的值,实际上大多在堆上
x = 42 # 小整数可能被缓存,但概念上在堆
y = [1, 2, 3] # 列表对象在堆上
z = "hello" # 字符串在堆上(可能被intern)
# 函数调用信息在调用栈上,但对象数据在堆上
return x + len(y)
result = stack_vs_heap()
Rust中的栈和堆策略
// Rust - 明确的栈/堆控制
fn stack_vs_heap_rust() {
// 栈上分配 - 快速,自动管理
let x: i32 = 42; // 在栈上
let y: [i32; 3] = [1, 2, 3]; // 固定大小数组在栈上
let z: &str = "hello"; // 字符串字面量在程序段,引用在栈上
// 堆上分配 - 灵活,需要显式管理
let vec: Vec<i32> = vec![1, 2, 3]; // Vec的缓冲区在堆上
let string: String = String::from("hello"); // String数据在堆上
let boxed: Box<i32> = Box::new(42); // 明确在堆上分配
println!("Stack: {}, {}, {}", x, y[0], z);
println!("Heap: {}, {}, {}", vec[0], string, boxed);
}
// 演示栈上复杂结构
#[derive(Debug)]
struct Point {
x: f64,
y: f64,
}
#[derive(Debug)]
struct Rectangle {
top_left: Point,
bottom_right: Point,
}
fn geometric_on_stack() {
// 整个结构都在栈上 - 零分配开销
let rect = Rectangle {
top_left: Point { x: 0.0, y: 10.0 },
bottom_right: Point { x: 10.0, y: 0.0 },
};
let area = (rect.bottom_right.x - rect.top_left.x) *
(rect.top_left.y - rect.bottom_right.y);
println!("Rectangle: {:?}, Area: {}", rect, area);
}
8.3 智能指针与内存管理
Python的引用管理
# Python - 隐式引用管理
import weakref
from typing import Optional
class Node:
def __init__(self, value: int):
self.value = value
self.children: list['Node'] = []
self.parent: Optional['Node'] = None
def add_child(self, child: 'Node'):
child.parent = self # 可能创建循环引用
self.children.append(child)
# 创建可能导致内存泄漏的结构
def create_circular_reference():
parent = Node(1)
child = Node(2)
parent.add_child(child)
# 如果parent和child互相引用,可能需要GC来清理
return parent
# 使用弱引用避免循环
class SafeNode:
def __init__(self, value: int):
self.value = value
self.children: list['SafeNode'] = []
self._parent: Optional[weakref.ref] = None
@property
def parent(self) -> Optional['SafeNode']:
return self._parent() if self._parent else None
@parent.setter
def parent(self, value: Optional['SafeNode']):
self._parent = weakref.ref(value) if value else None
Rust的智能指针
use std::rc::{Rc, Weak};
use std::cell::RefCell;
// 使用Rc<T>进行共享所有权
#[derive(Debug)]
struct Node {
value: i32,
children: Vec<Rc<RefCell<Node>>>,
parent: Option<Weak<RefCell<Node>>>, // 使用Weak避免循环引用
}
impl Node {
fn new(value: i32) -> Rc<RefCell<Self>> {
Rc::new(RefCell::new(Node {
value,
children: Vec::new(),
parent: None,
}))
}
fn add_child(parent: &Rc<RefCell<Node>>, child: Rc<RefCell<Node>>) {
// 设置子节点的父节点(弱引用)
child.borrow_mut().parent = Some(Rc::downgrade(parent));
// 添加子节点到父节点
parent.borrow_mut().children.push(child);
}
}
fn demonstrate_smart_pointers() {
// 创建节点
let parent = Node::new(1);
let child1 = Node::new(2);
let child2 = Node::new(3);
// 建立父子关系
Node::add_child(&parent, child1.clone());
Node::add_child(&parent, child2.clone());
// 访问数据
println!("Parent value: {}", parent.borrow().value);
println!("Child1 value: {}", child1.borrow().value);
// 通过弱引用访问父节点
if let Some(parent_ref) = child1.borrow().parent.as_ref() {
if let Some(parent_strong) = parent_ref.upgrade() {
println!("Child1's parent value: {}", parent_strong.borrow().value);
}
}
// 当所有强引用都销毁时,节点会自动清理
// 不会有循环引用导致的内存泄漏
}
// Box<T>用于堆上单一所有权
fn demonstrate_box() {
// 递归数据结构必须使用Box
#[derive(Debug)]
enum List {
Cons(i32, Box<List>),
Nil,
}
use List::{Cons, Nil};
let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
println!("List: {:?}", list);
}
8.4 生命周期与借用检查器
Python的作用域管理
# Python - 运行时作用域管理
def demonstrate_scope():
data = [1, 2, 3, 4, 5]
def process_data():
# 可以访问外层作用域的变量
return [x * 2 for x in data]
def get_reference():
# 返回对局部变量的引用 - Python中这样做是安全的
# 因为GC会确保对象在有引用时不被回收
local_list = [1, 2, 3]
return local_list # 返回引用
result = process_data()
ref = get_reference() # 这在Python中是安全的
return result, ref
# Python允许这种模式,因为有GC保护
result, ref = demonstrate_scope()
print(result, ref) # 安全执行
Rust的生命周期系统
// Rust - 编译时生命周期检查
fn demonstrate_lifetimes() {
let data = vec![1, 2, 3, 4, 5];
// 借用checker确保引用的有效性
let result = process_data(&data);
println!("Processed: {:?}", result);
// 这段代码不会编译 - 生命周期错误
// let dangling_ref = get_dangling_reference();
}
fn process_data(data: &[i32]) -> Vec<i32> {
data.iter().map(|x| x * 2).collect()
}
// 这个函数不会编译
/*
fn get_dangling_reference() -> &Vec<i32> {
let local_vec = vec![1, 2, 3];
&local_vec // 错误:返回对局部变量的引用
}
*/
// 正确的做法:返回所有权而不是引用
fn get_owned_data() -> Vec<i32> {
let local_vec = vec![1, 2, 3];
local_vec // 转移所有权
}
// 或者使用生命周期参数
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
fn demonstrate_lifetime_annotations() {
let string1 = String::from("long string is long");
let string2 = String::from("xyz");
let result = longest(&string1, &string2);
println!("The longest string is: {}", result);
// 这段代码不会编译 - 生命周期不匹配
/*
let result;
{
let string2 = String::from("xyz");
result = longest(&string1, &string2);
} // string2在此处销毁
println!("The longest string is: {}", result); // 错误:result引用已销毁的数据
*/
}
8.5 性能优化技巧
Python性能优化
# Python - 运行时优化策略
import time
import sys
from typing import List
def python_optimization_techniques():
# 1. 列表推导式 vs 循环
data = list(range(1000000))
# 慢:普通循环
start = time.time()
result1 = []
for x in data:
if x % 2 == 0:
result1.append(x * 2)
time1 = time.time() - start
# 快:列表推导式
start = time.time()
result2 = [x * 2 for x in data if x % 2 == 0]
time2 = time.time() - start
print(f"Loop: {time1:.4f}s, List comp: {time2:.4f}s")
# 2. 使用局部变量避免全局查找
def slow_function():
total = 0
for i in range(100000):
total += len(str(i)) # 每次都查找全局len和str
return total
def fast_function():
local_len = len # 缓存到局部变量
local_str = str
total = 0
for i in range(100000):
total += local_len(local_str(i))
return total
# 3. 使用__slots__减少内存使用
class RegularClass:
def __init__(self, x, y):
self.x = x
self.y = y
class OptimizedClass:
__slots__ = ['x', 'y']
def __init__(self, x, y):
self.x = x
self.y = y
# 测试内存使用
regular_objects = [RegularClass(i, i*2) for i in range(10000)]
optimized_objects = [OptimizedClass(i, i*2) for i in range(10000)]
print(f"Regular class size: {sys.getsizeof(regular_objects[0])} bytes")
print(f"Optimized class size: {sys.getsizeof(optimized_objects[0])} bytes")
# 使用NumPy进行数值计算优化
try:
import numpy as np
def numpy_optimization():
# Python列表 vs NumPy数组
python_list = list(range(1000000))
numpy_array = np.arange(1000000)
# Python操作
start = time.time()
python_result = [x * 2 + 1 for x in python_list]
python_time = time.time() - start
# NumPy操作
start = time.time()
numpy_result = numpy_array * 2 + 1
numpy_time = time.time() - start
print(f"Python list: {python_time:.4f}s")
print(f"NumPy array: {numpy_time:.4f}s")
print(f"Speedup: {python_time / numpy_time:.2f}x")
except ImportError:
print("NumPy not available for optimization demo")
Rust性能优化
use std::time::Instant;
// Rust - 编译时优化和零成本抽象
fn rust_optimization_techniques() {
println!("=== Rust Performance Optimization ===");
// 1. 迭代器 vs 索引访问
let data: Vec<i32> = (0..1_000_000).collect();
// 使用索引(较慢)
let start = Instant::now();
let mut result1 = Vec::new();
for i in 0..data.len() {
if data[i] % 2 == 0 {
result1.push(data[i] * 2);
}
}
let time1 = start.elapsed();
// 使用迭代器(更快,零成本抽象)
let start = Instant::now();
let result2: Vec<i32> = data
.iter()
.filter(|&&x| x % 2 == 0)
.map(|&x| x * 2)
.collect();
let time2 = start.elapsed();
println!("Index access: {:?}", time1);
println!("Iterator: {:?}", time2);
println!("Speedup: {:.2}x", time1.as_secs_f64() / time2.as_secs_f64());
// 2. 避免不必要的分配
demonstrate_allocation_optimization();
// 3. 使用引用避免拷贝
demonstrate_reference_optimization();
// 4. 内联和编译器优化
demonstrate_inlining();
}
fn demonstrate_allocation_optimization() {
let strings = vec!["hello", "world", "rust", "performance"];
// 低效:每次都分配新字符串
let start = Instant::now();
let mut result1 = String::new();
for s in &strings {
result1 = result1 + s + " "; // 每次都重新分配
}
let time1 = start.elapsed();
// 高效:预分配容量
let start = Instant::now();
let mut result2 = String::with_capacity(100); // 预分配
for s in &strings {
result2.push_str(s);
result2.push(' ');
}
let time2 = start.elapsed();
// 最高效:使用join
let start = Instant::now();
let result3 = strings.join(" ");
let time3 = start.elapsed();
println!("String concat: {:?}", time1);
println!("Pre-allocated: {:?}", time2);
println!("Join: {:?}", time3);
}
fn demonstrate_reference_optimization() {
#[derive(Clone)]
struct LargeData {
data: Vec<i32>,
}
impl LargeData {
fn new(size: usize) -> Self {
LargeData {
data: (0..size).map(|i| i as i32).collect(),
}
}
// 低效:按值传递
fn process_by_value(self) -> i32 {
self.data.iter().sum()
}
// 高效:按引用传递
fn process_by_reference(&self) -> i32 {
self.data.iter().sum()
}
}
let large_data = LargeData::new(100000);
// 测试按引用传递的性能优势
let start = Instant::now();
let result = large_data.process_by_reference();
let time_ref = start.elapsed();
let start = Instant::now();
let result_clone = large_data.clone().process_by_value();
let time_val = start.elapsed();
println!("By reference: {:?}", time_ref);
println!("By value (clone): {:?}", time_val);
assert_eq!(result, result_clone);
}
// 内联函数优化
#[inline]
fn fast_calculation(x: f64, y: f64) -> f64 {
x * x + y * y
}
#[inline(never)] // 强制不内联,用于对比
fn slow_calculation(x: f64, y: f64) -> f64 {
x * x + y * y
}
fn demonstrate_inlining() {
let data: Vec<(f64, f64)> = (0..100000)
.map(|i| (i as f64, (i * 2) as f64))
.collect();
// 内联函数
let start = Instant::now();
let result1: f64 = data
.iter()
.map(|(x, y)| fast_calculation(*x, *y))
.sum();
let time1 = start.elapsed();
// 非内联函数
let start = Instant::now();
let result2: f64 = data
.iter()
.map(|(x, y)| slow_calculation(*x, *y))
.sum();
let time2 = start.elapsed();
println!("Inlined function: {:?}", time1);
println!("Non-inlined function: {:?}", time2);
assert!((result1 - result2).abs() < 1e-10);
}
8.6 内存布局优化
结构体布局优化
// 展示内存布局对性能的影响
use std::mem;
// 低效的内存布局
#[repr(C)]
struct UnoptimizedStruct {
a: u8, // 1 byte
b: u64, // 8 bytes (需要7字节填充)
c: u8, // 1 byte
d: u32, // 4 bytes (需要3字节填充)
}
// 优化后的内存布局
#[repr(C)]
struct OptimizedStruct {
b: u64, // 8 bytes
d: u32, // 4 bytes
a: u8, // 1 byte
c: u8, // 1 byte (总共2字节填充)
}
fn demonstrate_memory_layout() {
println!("=== Memory Layout Optimization ===");
println!("Unoptimized struct size: {} bytes",
mem::size_of::<UnoptimizedStruct>());
println!("Optimized struct size: {} bytes",
mem::size_of::<OptimizedStruct>());
// 对于大量结构体,内存布局优化可以显著减少内存使用
let unoptimized_vec: Vec<UnoptimizedStruct> = (0..10000)
.map(|i| UnoptimizedStruct {
a: (i % 256) as u8,
b: i as u64,
c: ((i * 2) % 256) as u8,
d: (i * 3) as u32,
})
.collect();
let optimized_vec: Vec<OptimizedStruct> = (0..10000)
.map(|i| OptimizedStruct {
a: (i % 256) as u8,
b: i as u64,
c: ((i * 2) % 256) as u8,
d: (i * 3) as u32,
})
.collect();
let unoptimized_memory = unoptimized_vec.len() * mem::size_of::<UnoptimizedStruct>();
let optimized_memory = optimized_vec.len() * mem::size_of::<OptimizedStruct>();
println!("Unoptimized vector memory: {} bytes", unoptimized_memory);
println!("Optimized vector memory: {} bytes", optimized_memory);
println!("Memory saved: {} bytes ({:.1}%)",
unoptimized_memory - optimized_memory,
((unoptimized_memory - optimized_memory) as f64 / unoptimized_memory as f64) * 100.0);
}
// 缓存友好的数据结构
#[derive(Clone)]
struct Point3D {
x: f32,
y: f32,
z: f32,
}
// SoA (Structure of Arrays) - 缓存友好
struct Points3D {
x: Vec<f32>,
y: Vec<f32>,
z: Vec<f32>,
}
impl Points3D {
fn new() -> Self {
Points3D {
x: Vec::new(),
y: Vec::new(),
z: Vec::new(),
}
}
fn push(&mut self, point: Point3D) {
self.x.push(point.x);
self.y.push(point.y);
self.z.push(point.z);
}
fn len(&self) -> usize {
self.x.len()
}
}
fn demonstrate_cache_efficiency() {
use std::time::Instant;
const N: usize = 1_000_000;
// AoS (Array of Structures)
let points_aos: Vec<Point3D> = (0..N)
.map(|i| Point3D {
x: i as f32,
y: (i * 2) as f32,
z: (i * 3) as f32,
})
.collect();
// SoA (Structure of Arrays)
let mut points_soa = Points3D::new();
for i in 0..N {
points_soa.push(Point3D {
x: i as f32,
y: (i * 2) as f32,
z: (i * 3) as f32,
});
}
// 测试只访问x坐标的性能
let start = Instant::now();
let sum_aos: f32 = points_aos.iter().map(|p| p.x).sum();
let time_aos = start.elapsed();
let start = Instant::now();
let sum_soa: f32 = points_soa.x.iter().sum();
let time_soa = start.elapsed();
println!("=== Cache Efficiency Test ===");
println!("AoS sum: {} in {:?}", sum_aos, time_aos);
println!("SoA sum: {} in {:?}", sum_soa, time_soa);
println!("SoA speedup: {:.2}x", time_aos.as_secs_f64() / time_soa.as_secs_f64());
}
8.7 实践练习
练习1:内存池实现
// 实现一个简单的内存池来减少分配开销
use std::collections::VecDeque;
struct MemoryPool<T> {
available: VecDeque<Box<T>>,
in_use: usize,
}
impl<T> MemoryPool<T> {
fn new() -> Self {
MemoryPool {
available: VecDeque::new(),
in_use: 0,
}
}
fn acquire(&mut self) -> Box<T>
where
T: Default
{
match self.available.pop_front() {
Some(item) => {
self.in_use += 1;
item
}
None => {
self.in_use += 1;
Box::new(T::default())
}
}
}
fn release(&mut self, item: Box<T>) {
self.available.push_back(item);
self.in_use -= 1;
}
fn stats(&self) -> (usize, usize) {
(self.in_use, self.available.len())
}
}
// 测试内存池性能
fn test_memory_pool() {
use std::time::Instant;
#[derive(Default)]
struct LargeObject {
data: [u8; 1024], // 1KB对象
}
const ITERATIONS: usize = 100_000;
// 不使用内存池
let start = Instant::now();
for _ in 0..ITERATIONS {
let obj = Box::new(LargeObject::default());
// 使用obj...
drop(obj); // 立即释放
}
let time_without_pool = start.elapsed();
// 使用内存池
let mut pool = MemoryPool::new();
let start = Instant::now();
for _ in 0..ITERATIONS {
let obj = pool.acquire();
// 使用obj...
pool.release(obj); // 返回到池中
}
let time_with_pool = start.elapsed();
println!("=== Memory Pool Performance ===");
println!("Without pool: {:?}", time_without_pool);
println!("With pool: {:?}", time_with_pool);
println!("Speedup: {:.2}x", time_without_pool.as_secs_f64() / time_with_pool.as_secs_f64());
println!("Pool stats: {:?}", pool.stats());
}
fn main() {
demonstrate_smart_pointers();
demonstrate_box();
demonstrate_lifetimes();
demonstrate_lifetime_annotations();
rust_optimization_techniques();
demonstrate_memory_layout();
demonstrate_cache_efficiency();
test_memory_pool();
}
练习2:性能分析器
// 实现一个简单的性能分析器
use std::time::{Instant, Duration};
use std::collections::HashMap;
pub struct Profiler {
timers: HashMap<String, Duration>,
starts: HashMap<String, Instant>,
}
impl Profiler {
pub fn new() -> Self {
Profiler {
timers: HashMap::new(),
starts: HashMap::new(),
}
}
pub fn start(&mut self, name: &str) {
self.starts.insert(name.to_string(), Instant::now());
}
pub fn end(&mut self, name: &str) {
if let Some(start_time) = self.starts.remove(name) {
let duration = start_time.elapsed();
*self.timers.entry(name.to_string()).or_insert(Duration::from_nanos(0)) += duration;
}
}
pub fn report(&self) {
println!("=== Performance Report ===");
let mut times: Vec<_> = self.timers.iter().collect();
times.sort_by_key(|(_, duration)| *duration);
times.reverse();
for (name, duration) in times {
println!("{}: {:?}", name, duration);
}
}
}
// 宏来简化性能测量
macro_rules! profile {
($profiler:expr, $name:expr, $block:block) => {
$profiler.start($name);
let result = $block;
$profiler.end($name);
result
};
}
fn demonstrate_profiler() {
let mut profiler = Profiler::new();
// 测试不同算法的性能
let data: Vec<i32> = (0..100_000).collect();
// 冒泡排序
profile!(profiler, "bubble_sort", {
let mut data_copy = data.clone();
bubble_sort(&mut data_copy);
});
// 快速排序
profile!(profiler, "quick_sort", {
let mut data_copy = data.clone();
data_copy.sort(); // Rust的标准排序算法
});
// 计算密集型操作
profile!(profiler, "computation", {
let _result: f64 = (0..10_000)
.map(|i| (i as f64).sin().cos().tan())
.sum();
});
profiler.report();
}
fn bubble_sort(arr: &mut [i32]) {
let len = arr.len();
for i in 0..len {
for j in 0..len - 1 - i {
if arr[j] > arr[j + 1] {
arr.swap(j, j + 1);
}
}
}
}
8.8 对比总结
特性 | Python | Rust |
---|---|---|
内存管理 | 垃圾回收 | 所有权系统 |
性能开销 | 运行时GC开销 | 零运行时开销 |
内存安全 | 运行时检查 | 编译时保证 |
内存布局控制 | 有限 | 完全控制 |
缓存效率 | 依赖解释器实现 | 可优化 |
内存泄漏 | 可能(循环引用) | 编译器防止 |
开发复杂度 | 简单 | 需要理解所有权 |
总结
第8章深入探讨了Rust的内存管理和性能优化策略。Rust通过所有权系统实现了零成本抽象和确定性内存管理,这与Python的垃圾回收机制形成了鲜明对比。理解这些概念对于编写高性能的Rust代码至关重要。
在下一章中,我们将学习Rust的并发编程模型,了解如何安全高效地编写多线程程序。