rust单元类型

Posted 不想再做笨蛋了

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了rust单元类型相关的知识,希望对你有一定的参考价值。

rust中一个妙妙类型叫单元类型,其表示为(),对就是一对括号,唯一的值也是 ()。

这个类型有什么作用呢。

1 做函数的返回值

震撼我一整年,fn main()中的()main函数的返回值。

你不能说 main 函数无返回值,因为没有返回值的函数在 Rust 中是有单独的定义的:发散函数( diverge function ),顾名思义,无法收敛的函数。

2 map中的占位符

你可以用 () 作为 map 的值,表示我们不关注具体的值,只关注 key。 这种用法和 Go 语言的 struct 类似,可以作为一个值用来占位,但是完全不占用任何内存。

为啥不打印!在 Rust 单元测试中工作?

【中文标题】为啥不打印!在 Rust 单元测试中工作?【英文标题】:Why doesn't println! work in Rust unit tests?为什么不打印!在 Rust 单元测试中工作? 【发布时间】:2014-09-26 05:03:53 【问题描述】:

我已经实现了以下方法和单元测试:

use std::fs::File;
use std::path::Path;
use std::io::prelude::*;

fn read_file(path: &Path) 
    let mut file = File::open(path).unwrap();
    let mut contents = String::new();
    file.read_to_string(&mut contents).unwrap();
    println!("", contents);


#[test]
fn test_read_file() 
    let path = &Path::new("/etc/hosts");
    println!(":?", path);
    read_file(path);

我以这种方式运行单元测试:

rustc --test app.rs; ./app

我也可以运行它

cargo test

我收到一条消息,说测试通过了,但 println! 从未显示在屏幕上。为什么不呢?

【问题讨论】:

【参考方案1】:

这是因为 Rust 测试程序隐藏了成功测试的标准输出,以使测试输出整洁。您可以通过将--nocapture 选项传递给测试二进制文件或cargo test 来禁用此行为(但是,在这种情况下之后 -- - 见下文):

#[test]
fn test() 
    println!("Hidden output")

调用测试:

% rustc --test main.rs; ./main

running 1 test
test test ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

% ./main --nocapture

running 1 test
Hidden output
test test ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

% cargo test -- --nocapture

running 1 test
Hidden output
test test ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

但是,如果测试失败,无论是否存在此选项,都会打印其标准输出。

【讨论】:

您提到将 --nocapture 选项传递给 cargo test,但 cargo 无法为我识别此标志(使用 rustup.sh 的最新夜间)。你确定它应该工作吗? @JimGarrison,确实是there is an issue。同时你可以使用cargo test -- --nocapture,它应该可以工作。 谢谢!与这个问题无关,但这也帮助我弄清楚如何让cargo test [--] --bench 也能工作! @Nashenas,该选项称为nocapture,而不是no-capture @Anonyme2000 --nocapture 在 2018 版中仍然有效。 --show-output 是另一个选项,它以更易于查看的格式组织输出。【参考方案2】:

TL;DR

$ cargo test -- --nocapture

使用以下代码:

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum PieceShape 
    King, Queen, Rook, Bishop, Knight, Pawn


fn main() 
    println!("Hello, world!");


#[test]
fn demo_debug_format() 
    let q = PieceShape::Queen;
    let p = PieceShape::Pawn;
    let k = PieceShape::King;
    println!("q=:? p=:? k=:?", q, p, k);

然后运行以下命令:

 $ cargo test -- --nocapture

你应该看到

Running target/debug/chess-5d475d8baa0176e4

running 1 test
q=Queen p=Pawn k=King
test demo_debug_format ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

【讨论】:

cargo test -- --no-capture 不再有效。我收到以下错误:thread '<main>' panicked at '"Unrecognized option: \'no-capture\'."', ../src/libtest/lib.rs:249 不知这个问题github.com/rust-lang/cargo/issues/1377是不是有问题? 正如之前的 cmets 中所指出的,选项是 --nocapture,而不是 --no-capture。但是,鉴于我们经常遇到的大多数命令行约定,这是一个完全明显的错误。我只是完全按照 rust 1.1 (cargo 0.2.0) 中的这个答案中的描述使用了这个选项,它的工作原理和宣传的完全一样。【参考方案3】:

作为mentioned by L. F.,--show-output 是要走的路。

$ cargo test -- --show-output

其他显示标志为mentioned in the documentation of cargo test in display-options。

【讨论】:

注意--show-output 仅打印成功测试的标准输出。 这很有帮助。奇怪的额外——在 CL 上让我很困惑。我只需要运行一个测试并显示输出。看起来像 $ cargo test [test_name] -- --show-output【参考方案4】:

要包含带有println!() 的打印输出并保留测试结果的颜色,请在cargo test 中使用colornocapture 标志。

$ cargo test -- --color always --nocapture

(货运版本:每晚 0.13.0)

【讨论】:

【参考方案5】:

测试时,不显示标准输出。不要使用短信进行测试,而是使用assert!assert_eq!fail!。 Rust 的单元测试系统可以理解这些但不能理解文本消息。

即使出现问题,您编写的测试也会通过。让我们看看为什么:

read_to_end的签名是 fn read_to_end(&mut self) -> IoResult<Vec<u8>>

它返回一个IoResult 来指示成功或错误。这只是Result 的类型def,其错误值为IoError。由您决定如何处理错误。在这种情况下,我们希望任务失败,这是通过在 Result 上调用 unwrap 来完成的。

这将起作用:

let contents = File::open(&Path::new("message.txt"))
    .read_to_end()
    .unwrap();

unwrap 不应该被过度使用。

【讨论】:

真实信息,但不是 OP 的答案。

以上是关于rust单元类型的主要内容,如果未能解决你的问题,请参考以下文章

Rust Deref与自动解引用

Rust入坑指南:步步为营

算法leetcode1252. 奇数值单元格的数目(rust重拳出击)

算法leetcode1252. 奇数值单元格的数目(rust重拳出击)

Rust能力养成之(15)集成测试

Rust 第三章 数据类型