(done) 速通 rustlings(23) 特性 Traits

特性

特性 Traits 可以为已存在的类型/模块/结构体 添加方法,如下:

rust 复制代码
// The trait `AppendBar` has only one function which appends "Bar" to any object
// implementing this trait.
trait AppendBar {
    fn append_bar(self) -> Self;
}

impl AppendBar for String {
    // TODO: Implement `AppendBar` for the type `String`.
    fn append_bar(mut self) -> Self {
        self.push_str("Bar");
        self
    }
}

上面的代码定义了一个特性叫 AppendBar。随后为类型 String 实现了这个特性(往字符串末尾添加 "Bar")。

完整代码:

rust 复制代码
// The trait `AppendBar` has only one function which appends "Bar" to any object
// implementing this trait.
trait AppendBar {
    fn append_bar(self) -> Self;
}

impl AppendBar for String {
    // TODO: Implement `AppendBar` for the type `String`.
    fn append_bar(mut self) -> Self {
        self.push_str("Bar");
        self
    }
}

fn main() {
    let s = String::from("Foo");
    let s = s.append_bar();
    println!("s: {s}");
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn is_foo_bar() {
        assert_eq!(String::from("Foo").append_bar(), "FooBar");
    }

    #[test]
    fn is_bar_bar() {
        assert_eq!(String::from("").append_bar().append_bar(), "BarBar");
    }
}

更多例子:为 Vec 添加特性

样例代码:

rust 复制代码
trait AppendBar {
    fn append_bar(self) -> Self;
}

impl AppendBar for Vec<String> {
    fn append_bar(mut self) -> Self {
        //        ^^^ this is important
        self.push(String::from("Bar"));
        self
    }
}

特性的默认实现

直接在 trait 花括号内实现的函数属于该特性的默认实现,可以被所有实现该特性的结构体共享。

rust 复制代码
trait Licensed {
    // TODO: Add a default implementation for `licensing_info` so that
    // implementors like the two structs below can share that default behavior
    // without repeating the function.
    // The default license information should be the string "Default license".
    fn licensing_info(&self) -> String {
        "Default license".to_string()
    }
}

struct SomeSoftware {
    version_number: i32,
}

struct OtherSoftware {
    version_number: String,
}

impl Licensed for SomeSoftware {} // Don't edit this line.
impl Licensed for OtherSoftware {} // Don't edit this line.

特性的泛型

实现同一个特性的结构体有点类似于 "拥有同一个父类",如下:

rust 复制代码
trait Licensed {
    fn licensing_info(&self) -> String {
        "Default license".to_string()
    }
}

struct SomeSoftware;
struct OtherSoftware;

impl Licensed for SomeSoftware {}
impl Licensed for OtherSoftware {}

fn compare_license_types(software1: impl Licensed, software2: impl Licensed) -> bool {
    //                              ^^^^^^^^^^^^^             ^^^^^^^^^^^^^
    software1.licensing_info() == software2.licensing_info()
}

可以看到 impl Licensed 被作为了数据类型

若是实现了多个特性,还可以使用 impl trait1 + trait2 作为数据类型,如下:

rust 复制代码
trait SomeTrait {
    fn some_function(&self) -> bool {
        true
    }
}

trait OtherTrait {
    fn other_function(&self) -> bool {
        true
    }
}

struct SomeStruct;
impl SomeTrait for SomeStruct {}
impl OtherTrait for SomeStruct {}

struct OtherStruct;
impl SomeTrait for OtherStruct {}
impl OtherTrait for OtherStruct {}

fn some_func(item: impl SomeTrait + OtherTrait) -> bool {
    //             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    item.some_function() && item.other_function()
}

相关推荐
shimly1234562 小时前
(done) 速通 rustlings(17) 哈希表
rust
shimly1234563 小时前
(done) 速通 rustlings(15) 字符串
rust
shimly1234564 小时前
(done) 速通 rustlings(22) 泛型
rust
yezipi耶不耶5 小时前
我在 RTMate 里使用的高并发连接管理利器: DashMap
websocket·rust
初恋叫萱萱10 小时前
深入解析 Rust + LLM 开发:手把手教你写一个 AI 运维助手
运维·人工智能·rust
shimly12345618 小时前
(done) 速通 rustlings(9) 分支跳转
rust
shimly1234561 天前
(done) 速通 rustlings(4) 变量声明
rust
shimly1234561 天前
(done) 速通 rustlings(11) 向量vector及其操作
rust
shimly1234561 天前
(done) 速通 rustlings(3) intro1 println!()
rust