为什么#[derive(Show)] 不再起作用了?

Why does #[derive(Show)] not work anymore?

使用今天的 Rust nightly,以下代码不再编译:

#[derive(Show)]
enum S {
    A,
    B
}

fn main() {
    println!("{}", S::A);
}

相反,它给了我以下错误信息:

error: the trait `core::fmt::String` is not implemented for the type `S`

有没有办法恢复旧的行为?当然,不能要求为每种类型手动实现它。

答案是在format!中使用{:?}代替{}

旧的 Show 特征被拆分为 DisplayDebug

  • Display 专为面向用户的输出而设计,并使用 blank/default 格式说明符(例如 {}{:.10} {foo:} 都在使用 Display)

  • Debug 专为 debugging/internal 输出而设计,并使用 ? 格式说明符(例如 {:?}{:.10?}{foo:?} 都在使用 Debug)

因此,要使用 #[derive(Debug)] 创建的实现,应该写 println!("{:?}", ...),而不是旧的 println!("{}", ...)

只有 Debug 可以是 #[derive]d,因为在大多数情况下,像 Foo { x: 1, y: 2 } 这样的输出不太可能是正确的面向用户的输出(我敢肯定它适用于某些情况, 但随后程序员可以自己编写 Display 的实现,甚至直接调用 #[derive]d Debug 实现)。

这最初在 RFC 504 and there is ongoing discussion in RFC 565 中进行了描述,使上述指南更加具体。