(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()
}

相关推荐
rainchestnut1 天前
bevy初体验2-官方示例学习
rust
葡萄城技术团队1 天前
Hurley:用 Rust 打造的高性能 HTTP 客户端 + 压测工具
开发语言·http·rust
Source.Liu1 天前
【dxf-rs】库全面介绍
rust·dxf-rs
土豆12502 天前
Rust宏编程完全指南:用元编程解锁Rust的终极力量
rust·编程语言
小杍随笔2 天前
【Rust 语言编程知识与应用:基础数据类型详解】
开发语言·后端·rust
小杍随笔2 天前
【Rust 语言编程知识与应用:自定义数据类型详解】
开发语言·后端·rust
咚为2 天前
Rust 跨平台编译实战:从手动配置到 Cross 容器化
开发语言·后端·rust
幸福指北2 天前
我用 Tauri + Vue 3 + Rust 开发了一款跨平台网络连接监控工具Portview,性能炸裂!
前端·网络·vue.js·tcp/ip·rust
咚为2 天前
深入浅出 Rust FFI:从内存安全到二进制兼容
开发语言·安全·rust
a1117762 天前
剪切板助手TieZ(开源项目rust)
rust·开源·剪切板