我尝试用let myvar =1..5;
创建一个范围,然后用{:?}
化程序和for循环打印出来。如果我理解正确的话,range是Rust中的迭代器,如果{:?}
可以用来打印数组中的所有值,那么它应该可以对range做同样的事情。
然而,当我尝试在main函数中运行这些函数时:
let myvar=1..5;
println!("{:?}",myvar);
for i in myvar{
println!("{i}");
}
我得到了这些结果。
1..5
1
2
3
4
我期望看到的是1234
,而不是1..5
器打印出的范围值。我正在运行rustc 1.69.0(84 c898 d 65 2023-04-16)。
如果这是一个基本的问题,我提前道歉,因为我已经在很多地方搜索过了,没有找到这样的问题(或者,或者我只是没有用正确的术语搜索)。
2条答案
按热度按时间fnvucqvd1#
对于一个范围来说,打印出每个元素作为其调试输出是没有多大意义的。
首先,范围并不总是用作数字序列;它同样用于表示某些“界限”。如果输出包含每个单独的数字,那么调试
x: 10..100
和y: 40..60
之间的矩形会很麻烦。当传递给BTreeMap
s上的.range()
时,也用作边界。其次,数组表示元素的集合,因此在调试时,了解这些元素是什么会很有帮助。另一方面,范围不是集合,您不需要显式显示该范围内的所有值。它“包含”大于起始值且小于结束值的元素是微不足道的。
第三,Rust迭代器通常是惰性的和只读的;它们需要修改以进行并产生每个元素。调试语句耗尽底层迭代器是意料之外的(如果没有内部可变性,通常是不可能的)。
Range
可以例外,因为它是平凡的可克隆的,但这不是所有迭代器的属性。snz8szmq2#
如果
{:?}
可以用来打印出数组中的所有值,那么它应该能够对范围做同样的事情{:?}
所做的就是使用Debug
trait的值实现来格式化值。由值的实现来决定如何表示该值。简单地说,数组类型和范围类型以不同的方式实现了这个trait。我认为范围的实现比打印出范围中的所有值更有用。考虑像
1..1000000
这样的大范围。如果您试图在调试期间检查范围以查看它包含的内容,则显示范围的端点比转储范围在语义上包含的每个值要有用得多。更一般地说,在调试过程中,你通常更关心 * 值的状态 *,而不太关心 * 值在某些情况下做什么。还值得注意的是,并没有针对所有迭代器的
Debug
的全面实现--单个迭代器类型可以选择实现Debug
,也可以选择不实现。