In Rust, 'for loops' can print all the values in a Rust range, but {:?} does not print all the values in a range

huangapple go评论64阅读模式
英文:

In Rust, 'for loops' can print all the values in a Rust range, but {:?} does not print all the values in a range

问题

我尝试使用 let myvar =1..5; 创建了一个范围,然后使用 {:?} 格式化符号和 for 循环打印出它。如果我理解正确的话,在 Rust 中,范围是迭代器,如果 {:?} 可以用于打印数组中的所有值,它应该也可以用于范围。

然而,当我在我的主函数中尝试运行这些代码时:

let myvar = 1..5;
println!("{:?}", myvar);

for i in myvar {
    println!("{}", i);
}

我得到了以下结果:

1..5 

1
2
3
4

我期望的是在由 {:?} 格式化符号打印的范围值中看到 1234,而不是 1..5。我正在运行的是 Rust 版本 1.69.0(84c898d65 2023-04-16)。

如果这是一个基本问题,我提前道歉,因为我已经在很多地方搜索过,但找不到类似的问题(要么是这样,要么是我没有用正确的术语搜索)。

英文:

I tried creating a range with let myvar =1..5;, and then printing it out with both the {:?} formatter and a for loop. If I understand correctly, ranges are iterators in Rust, if {:?} can be used to print out all the values in an array, it should be able to do the same for a range.

However, when I tried running these in my main function:

let myvar=1..5;
println!("{:?}",myvar);

for i in myvar{
println!("{i}");
}

I got these results instead.

1..5 

1
2
3
4

What I expect is to see 1234 for the range values printed out by {:?} formatter instead of 1..5. I'm running rustc 1.69.0 (84c898d65 2023-04-16).

I apologize in advance if this is a basic question, as I have searched in quite a few places and could not find an issue like this (either that, or I'm just not searching with the correct terms).

答案1

得分: 3

如果{:?}可以用来打印数组中的所有值,那么它也应该能够对范围执行相同的操作。

{:?}仅仅是使用值的Debug特性的实现来格式化该值。如何表示该值是由该值的实现来决定的。

简单来说,数组类型和范围类型以不同的方式实现了这个特性。我认为范围的实现比打印范围中的所有值更有用。考虑一个巨大的范围,比如1..1000000。如果您在调试过程中尝试检查范围以查看其包含的内容,显示范围的端点要比转储范围在语义上包含的每个值更有用。更一般地说,在调试过程中,您通常更关心_值的状态_,而不太关心_值在某些情况下的行为_。

值得注意的是,并没有为所有迭代器提供Debug的通用实现——各个迭代器类型可以选择实现Debug,也可以选择不实现。

英文:

> if {:?} can be used to print out all the values in an array, it should be able to do the same for a range

All {:?} does is format the value using the value's implementation of the Debug trait. It is up to the value's implementation to decide how to represent the value.

Simply, the array type and range types implement this trait differently. I would argue that the implementation for ranges is more useful than printing out all of the values in the range. Consider a huge range like 1..1000000. If you are trying to inspect a range during debugging to see what it contains, displaying the endpoints of the range is substantially more useful than dumping every value the range semantically contains. More generally, during debugging you usually care more about the value's state and less about what the value does under certain circumstances.

It's also worth noting that there is no blanket implementation of Debug for all iterators -- individual iterator types can choose to implement Debug, or choose not to.

答案2

得分: 3

不要翻译的部分: "It does not make much sense for a range to print out every element for its debug output."、"For one, a range is not always used as a sequence of numbers; it is equally used to represent the some "bounds"."、"It would be annoying to debug a rectangle that exists in space between x: 10..100 and y: 40..60 if that output contained each individual number."、"Also used as bounds when passed to .range() on BTreeMaps."、"Secondly, an array represents a collection of elements and thus when debugging it would be helpful to know what those elements are."、"A range on the otherhand is not a collection and you do not need to explicitly show what all values are within that range."、"Its trivial to see it would "contain" elements larger than the starting value, and less than the ending value."、"Thirdly, Rust iterators in general are lazy and read-once; they require modification to progress and yield each element."、"It would be unexpected for a debug statement to exhaust the underlying iterator (and not possible in general without interior mutability)."、"Range could make an exception since it is trivially clonable, but that is not a property of all iterators."

翻译部分:对于范围来说,每个元素都打印在调试输出中并没有太多意义。

首先,范围并不总是用作数字序列;它同样用于表示一些"边界"。如果输出包含每个单独的数字,那么调试存在于x: 10..100y: 40..60之间的矩形将会很烦人。它也用作传递给BTreeMap.range()时的边界。

其次,数组表示元素的集合,因此在调试时了解这些元素是有帮助的。另一方面,范围不是一个集合,你不需要明确显示范围内的所有值。很容易看出它将包含大于起始值且小于结束值的元素。

第三,Rust迭代器通常是惰性的且只读取一次;它们需要修改才能前进并产生每个元素。一个调试语句消耗底层迭代器是意外的(通常情况下没有内部可变性是不可能的)。Range可以作出例外,因为它可以轻松克隆,但这并不是所有迭代器的属性。

英文:

It does not make much sense for a range to print out every element for its debug output.

For one, a range is not always used as a sequence of numbers; it is equally used to represent the some "bounds". It would be annoying to debug a rectangle that exists in space between x: 10..100 and y: 40..60 if that output contained each individual number. Also used as bounds when passed to .range() on BTreeMaps.

Secondly, an array represents a collection of elements and thus when debugging it would be helpful to know what those elements are. A range on the otherhand is not a collection and you do not need to explicitly show what all values are within that range. Its trivial to see it would "contain" elements larger than the starting value, and less than the ending value.

Thirdly, Rust iterators in general are lazy and read-once; they require modification to progress and yield each element. It would be unexpected for a debug statement to exhaust the underlying iterator (and not possible in general without interior mutability). Range could make an exception since it is trivially clonable, but that is not a property of all iterators.

huangapple
  • 本文由 发表于 2023年5月29日 04:44:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76353528.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定