Rust 标准库中的可打印类型

RustRustBeginner
立即练习

This tutorial is from open-source community. Access the source code

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在本实验中,将解释为了使用 std::fmt 格式化特性,类型必须有一个可打印的实现,对于 std 库中的类型,该实现可以自动提供。对于其他类型,可以派生 fmt::Debug 特性以启用打印。fmt::Debug 特性使实现可打印类型变得很直接,而 fmt::Display 则需要手动实现。fmt::Debug 特性允许所有类型派生打印实现,对于 std 库类型,{:?} 也是如此。本实验还提到了使用 {:?} 进行打印,并提供了一个如何使用它来打印不同类型的示例。此外,还引入了使用 {:#?} 进行“漂亮打印”的概念,它提供了一种更优雅的数据结构表示形式。最后提到,可以手动实现 fmt::Display 以控制类型的显示。

注意:如果本实验未指定文件名,你可以使用任何你想要的文件名。例如,你可以使用 main.rs,并通过 rustc main.rs &&./main 进行编译和运行。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("Rust")) -.-> rust/DataTypesGroup(["Data Types"]) rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust(("Rust")) -.-> rust/MemorySafetyandManagementGroup(["Memory Safety and Management"]) rust(("Rust")) -.-> rust/BasicConceptsGroup(["Basic Concepts"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/DataTypesGroup -.-> rust/integer_types("Integer Types") rust/DataTypesGroup -.-> rust/string_type("String Type") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") rust/MemorySafetyandManagementGroup -.-> rust/lifetime_specifiers("Lifetime Specifiers") subgraph Lab Skills rust/variable_declarations -.-> lab-99187{{"Rust 标准库中的可打印类型"}} rust/integer_types -.-> lab-99187{{"Rust 标准库中的可打印类型"}} rust/string_type -.-> lab-99187{{"Rust 标准库中的可打印类型"}} rust/function_syntax -.-> lab-99187{{"Rust 标准库中的可打印类型"}} rust/expressions_statements -.-> lab-99187{{"Rust 标准库中的可打印类型"}} rust/lifetime_specifiers -.-> lab-99187{{"Rust 标准库中的可打印类型"}} end

调试

所有想要使用 std::fmt 格式化特性的类型都需要有一个可打印的实现。只有像 std 库中的类型才会提供自动实现。其他所有类型都必须以某种方式手动实现。

fmt::Debug 特性使这变得非常简单。所有类型都可以派生(自动创建)fmt::Debug 实现。但 fmt::Display 并非如此,它必须手动实现。

// 这个结构体既不能用 `fmt::Display` 打印,也不能用 `fmt::Debug` 打印。
struct UnPrintable(i32);

// `derive` 属性会自动创建使这个结构体能用 `fmt::Debug` 打印所需的实现。
#[derive(Debug)]
struct DebugPrintable(i32);

所有 std 库类型也都可以用 {:?} 自动打印:

// 为 `Structure` 派生 `fmt::Debug` 实现。`Structure` 是一个包含单个 `i32` 的结构体。
#[derive(Debug)]
struct Structure(i32);

// 将一个 `Structure` 放入 `Deep` 结构体中。也使其可打印。
#[derive(Debug)]
struct Deep(Structure);

fn main() {
    // 用 `{:?}` 打印类似于用 `{}` 打印。
    println!("{:?} months in a year.", 12);
    println!("{1:?} {0:?} is the {actor:?} name.",
             "Slater",
             "Christian",
             actor="actor's");

    // `Structure` 是可打印的!
    println!("Now {:?} will print!", Structure(3));

    // `derive` 的问题在于无法控制结果的样子。要是我只想让它显示一个 `7` 呢?
    println!("Now {:?} will print!", Deep(Structure(7)));
}

所以 fmt::Debug 肯定能让其可打印,但牺牲了一些优雅性。Rust 还提供了用 {:#?} 进行“漂亮打印”。

#[derive(Debug)]
struct Person<'a> {
    name: &'a str,
    age: u8
}

fn main() {
    let name = "Peter";
    let age = 27;
    let peter = Person { name, age };

    // 漂亮打印
    println!("{:#?}", peter);
}

可以手动实现 fmt::Display 来控制显示。

总结

恭喜你!你已经完成了调试实验。你可以在 LabEx 中练习更多实验来提升你的技能。