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 编译器的严格判定。
}