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

相关推荐
古城小栈2 小时前
从 cargo-whero 库中,找到提升 rust 的契机
开发语言·后端·rust
techdashen7 小时前
Cloudflare 为何抛弃 NGINX,用 Rust 自研了一个代理
运维·nginx·rust
Mr.Rice.Fool10 小时前
rust面试经验1
后端·面试·职场和发展·rust
本地化文档11 小时前
rust-nomicon-l10n
rust·github·gitcode
代码羊羊11 小时前
Rust 格式化输出完全攻略:从入门到精通
开发语言·后端·rust
Rust研习社11 小时前
Rust + PostgreSQL 极简技术栈应用开发
开发语言·数据库·后端·http·postgresql·rust
古城小栈12 小时前
rust 亿级并发模型,实践完成
开发语言·网络·rust
qcx2313 小时前
Warp源码深度解析(一):GPU加速+AI Agent的下一代终端架构全景
人工智能·架构·rust
暮色念了红尘13 小时前
CC Switch — Ubuntu 20.04 可用版本
ubuntu·ai·rust·ubuntu 20.04·vibe coding·cc swich