Skip to content

Implementations 实现

impl 关键字用于为类型实现方法,它在 rust 代码里随处可见:

为类型实现方法(固有实现)

为类型(结构体、枚举也是类型)实现方法,也可以简单认为: impl + Struct = Class(其他语言的“类”,rust 使用这种方式即可实现)

rust
// 声明结构体(rust 的结构体,先声明后才能用于创建,不能直接创建实例)
struct Dog {
    name: String,
    age: u8,
}

// 为 Dog 的实现方法;impl 里面的是关联函数,与类型关联,与之相对的是自由函数。
impl Dog {
    // 这个方法用于初始化对象(创建结构体实例)
    fn new(name: &str, age: u8) -> Self {
        Dog {
            name: name.to_string(),
            age,
        }
    }

    // 其它实例方法
    fn bark(&self) {
        println!("{} 汪汪叫!", self.name);
    }
}

fn main() {
    let my_dog = Dog::new("小黑", 3);
    my_dog.bark(); // 输出:小黑 汪汪叫!
}

为类型实现遵守 Trait 的方法(Trait 实现)

当为类型实现方法时,若需要遵守某个 Trait(被某个trait约束),则需要使用 impl Trait for Struct 语法(就是多了个 trait名 for):

rust
// 一个共同 trait
pub trait Summary {
    fn summarize(&self) -> String;
}

// 第一个类型(结构体)
pub struct NewsArticle {
    pub headline: String,
    pub location: String,
    pub author: String,
    pub content: String,
}
// 为第一个类型实现受trait约束的方法
impl Summary for NewsArticle {
    fn summarize(&self) -> String {
        format!("{}, by {} ({})", self.headline, self.author, self.location)
    }
}

// 第二个类型(结构体)
pub struct SocialPost {
    pub username: String,
    pub content: String,
    pub reply: bool,
    pub repost: bool,
}
// 为第二个类型实现受trait约束的方法
impl Summary for SocialPost {
    fn summarize(&self) -> String {
        format!("{}: {}", self.username, self.content)
    }
}

当类型的方法传递泛型时(泛型实现)

当为泛型结构体实现方法时,需要使用 impl<T> StructName<T> {} 语法以实现泛型通用方法;可用 impl StructName<type> {} 实现某类型专用方法:

rust
// 以下代码演示了 泛型实现 的使用。
// 创建一个泛型结构体类型 Box,并为其实现通用方法和针对特定类型(i32)的专用方法

// 泛型结构体:可存放任意类型
struct Box<T> {
    content: T,
}

// 泛型实现块:适用于所有类型 T
impl<T> Box<T> {
    // impl内部为关联函数
    fn new(content: T) -> Self {
        Box { content }
    }

    // 通用方法:获取内容
    fn get_content(&self) -> &T {
        &self.content
    }
}

// 针对 i32 类型的专用实现
impl Box<i32> {
    // 专用方法:检查内容是否为正数
    fn is_positive(&self) -> bool {
        self.content > 0
    }
}

fn main() {
    // 使用字符串类型创建结构体实例
    let string_box = Box::new("Hello, Generics!");
    println!("String content: {}", string_box.get_content());

    // 使用 i32 类型创建结构体实例
    let number_box = Box::new(42);
    println!("Number content: {}", number_box.get_content());
    
    // 调用 i32 类型的专用方法
    println!("Is positive? {}", number_box.is_positive());
    
    // 尝试对字符串盒子调用 is_positive() 会编译失败(取消注释测试)
    // println!("{}", string_box.is_positive());
    // 因为只为 i32 类型实现了 is_positive 方法,没用为全部类型实现,所以无法通过 rust 编译器的严格判定。
}