使用 fmt::Display 打印

Printing using fmt::Display

我正在尝试使用 fmt::Display 打印枚举(或结构)。虽然代码编译并进入显示方法,但它不会打印值。

pub enum TestEnum<'a> {
   Foo(&'a str),
   Bar(f32)
}

impl<'b> fmt::Display for TestEnum <'b> {
    fn fmt(&self, f : &mut fmt::Formatter) -> fmt::Result {
        println!("Got this far");
        match self{
            &TestEnum::Foo(x) => write!(f,"{}",x),
            &TestEnum::Bar(x) => write!(f,"{}",x),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_print() {
        let cell = TestEnum::Str("foo");
        println!("Printing");
        println!("{}",cell); // No output here
    }
}

我试过使用 {:?} 和 {} 但无济于事。

测试运行程序似乎转移了标准输出;您应该考虑使用 assert!assert_eq! 或其他令人恐慌的方式来测试您的断言,而不是在测试中打印。

此外,由于名称不匹配,您的代码无法编译。我从 main:

开始按预期工作
use std::fmt;

pub enum TestEnum<'a> {
    Foo(&'a str),
    Bar(f32)
}

impl<'b> fmt::Display for TestEnum <'b> {
    fn fmt(&self, f : &mut fmt::Formatter) -> fmt::Result {
        match self {
            &TestEnum::Foo(x) => write!(f, "{}", x),
            &TestEnum::Bar(x) => write!(f, "{}", x),
        }
    }
}

fn main() {
    let cell = TestEnum::Foo("foo");
    println!("Printing");
    println!("{}", cell);
}

测试成功后,测试输出将重定向到缓冲区,以免与测试 "FAILED" 或 "ok" 消息混淆。


如果您只是想在开发测试时测试一些东西,您总是可以在测试结束时添加一个 panic!() 以确保它一直失败并输出所有日志记录。或者正如@AndreaP 在他的回答中指出的那样,您可以使用 cargo test -- --nocapture 来显示 all 测试的标准输出。


通常测试不应该写入标准输出,而是写入缓冲区并检查该缓冲区是否包含它应该包含的内容:

let cell = TestEnum::Foo("foo");
let mut buf = Vec::new();
let _ = write!(buf, "{}\n", cell);
assert_eq!(&buf, b"foo\n");

如果你真的想输出一些东西,你需要直接写到stdout。

let _ = write!(io::stdout(), "{}\n", cell);

但这会与测试的输出混合:

test tests::blub ... foo
ok

PlayPen

发生这种情况是因为 Rust 测试程序隐藏了成功测试的标准输出。您可以通过 --nocapture 选项来禁用此行为以测试二进制文件或 cargo test 命令:

cargo test -- --nocapture

PS: 您的代码是 broken/incomplete