泛型、trait 与生命周期

泛型、trait 与生命周期

1.泛型数据类型

泛型参数分为三类:

  • 生命周期参数
  • 类型参数
  • 常量参数

常量泛型参数

impl<const N: usize> Tokenizable for [u8; N]

2.trait

2.1 Copy

如果一个类型实现了 copy trait,使用它的变量不会发生所有权转移,而是直接复制值。在赋值给另一个变量之后,他仍然有效。基本数据类型默认实现了 copy trait

let x: i32 = 8;
let y: i32 = x;

print!("x = {}", x);

如果类型或其属性实现了 drop trait,则不允许实现 copy trait

2.2 Drop

2.3 Clone

Clone 继承了 Sized,这意味着只能为大小在编译时已知的类型实现 Clone。

pub trait Clone: Sized {
    fn clone(&self) -> Self;
    fn clone_from(&mut self, source: &Self) {
        *self = source.clone();
    }
}

当一个类型实现了 Clone 特性后,可以通过调用 clone 方法显式地创建一个新的独立副本,而不会影响原始值。

Clone 和 Copy 的区别

特性CloneCopy
拷贝方式显示调用clone()隐式浅拷贝(按位复制)
深浅拷贝深拷贝或自定义拷贝逻辑浅拷贝
自动派生可自动派生可自动派生
适用范围任务类型简单类型(大小固定)

自动派生

#[derive(Clone)]
struct MyStruct {
    a: i32,
    b: String,
}

自定义clone

struct Point {
    x: i32,
    y: i32,
}

impl Clone for Point {
    fn clone(&self) -> Self {
        println!("Cloning Point...");
        Point { x: self.x, y: self.y }
    }
}

fn main() {
    let p1 = Point { x: 1, y: 2 };
    let p2 = p1.clone();
    println!("p1: ({}, {}), p2: ({}, {})", p1.x, p1.y, p2.x, p2.y);
}

2.4 PartialEq

PartialEq 是一个用于比较类型是否相等的特性(trait)。

  • 为类型提供 == 和 != 运算符支持。
  • 实现 PartialEq 表明可以在类型实例之间判断 “部分等价性”。

2.5 Eq

Eq 是 PartialEq 的子特性,表示类型具有 “完全等价性”。

2.6 Send

Send 是一个标志性特性,表示类型的值可以安全地在线程之间移动(transfer ownership)。

  • 如果一个类型实现了 Send,则它可以被所有权转移到另一个线程。
  • Rust 的绝大多数类型都自动实现了 Send(例如,i32、String 等)。
use std::thread;

fn main() {
    let s = String::from("Hello");

    let handle = thread::spawn(move || {
        println!("{}", s); // 所有权转移到另一个线程
    });

    handle.join().unwrap();
}

2.7 Sync

Sync 是一个标志性特性,表示类型的引用可以安全地在多个线程中共享(共享引用 &T 是安全的)。

  • 如果一个类型实现了 Sync,则它的引用可以在线程之间共享。
  • Arc(原子引用计数)实现了 Sync,因此它的引用可以安全地在多个线程中共享。
use std::sync::Arc;
use std::thread;

fn main() {
    let s = Arc::new(String::from("Hello"));

    let s1 = Arc::clone(&s);
    let s2 = Arc::clone(&s);

    let handle1 = thread::spawn(move || {
        println!("{}", s1);
    });

    let handle2 = thread::spawn(move || {
        println!("{}", s2);
    });

    handle1.join().unwrap();
    handle2.join().unwrap();
}

2.8 Into

Into trait定义了一个方法into,它允许将一个类型转换成另一个类型。

pub trait Into<T>: Sized {
    fn into(self) -> T;
}

示例:

struct Wrapper(i32);

impl Into<Wrapper> for i32 {
    fn into(self) -> Wrapper {
        Wrapper(self)
    }
}

fn main() {
    let num: i32 = 5;
    let wrapped: Wrapper = num.into();
    println!("Wrapped value: {:?}", wrapped);
}

2.9 From

From trait定义了一个方法from,它允许从一个类型创建另一个类型。

pub trait From<T>: Sized {
    fn from(value: T) -> Self;
}

示例:

struct Wrapper(i32);

impl From<i32> for Wrapper {
    fn from(value: i32) -> Self {
        Wrapper(value)
    }
}

fn main() {
    let num: i32 = 5;
    let wrapped: Wrapper = Wrapper::from(num);
    println!("Wrapped value: {:?}", wrapped);
}
最后更新于