Rust迭代器和C ++迭代器之间的主要区别是什么? [英] What are the main differences between a Rust Iterator and C++ Iterator?

查看:131
本文介绍了Rust迭代器和C ++迭代器之间的主要区别是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C ++迭代器的一个典型示例是指针,它可用于指向C数组中的元素,如下所示:

 int array[] = {1, 2, 3, 4};
int* begin = std::begin(array); //Starting iterator
int* end = std::end(array) //Ending iterator

for(int* i = begin; i < end; i++)
{
    std::cout << *i << ',';
}

//Prints 1, 2, 3, 4
 

这很简单.

cplusplus.com 的迭代器的定义是

迭代器是指向一系列元素(例如数组或容器)中某个元素并能够使用一组运算符迭代该范围中的元素的任何对象...

这很有道理;在上面的代码中,有两个迭代器(beginend迭代器),并且使用了for循环并递增.

在Rust中,像这样使用迭代器:

 let vect = vec![1, 2, 3, 4];

let vect_iter = vect.iter();
 

什么?要对其进行迭代,请执行以下操作:

 vect_iter.next();
vect_iter.next();
 

我在Rust文档中找不到指针的任何确切定义,而是在查看 Iterator特征,似乎迭代器是容器的包装器,通过以某种方式标准化逻辑(如果完全有意义),可以简化处理./p>

我的主要问题是:

  1. 主要区别是什么?
  2. 为什么Rust会以这种方式使用迭代器,为什么它们表示的如此不同?
  3. C ++中有Rust类型的迭代器吗?
  4. Rust中有C ++类型的迭代器吗?
  5. 他们称呼某些特定内容吗? (内部/外部?)

解决方案

迭代器是一种编程语言中的概念,用于指代允许对元素的集合或序列进行迭代的构造.这个概念故意是模糊的,这是一个概念!它没有规定任何具体的实现方式.

为了更轻松地将C ++与Rust区别开,我将使用不同的名称:

  • C ++迭代器将被命名为光标
  • Rust迭代器将被命名为.

是的,这些完全是任意的.请注意,如果您查看Java或C#之类的语言,则会发现它们也使用流.


C ++

首先,不要使用cplusplus.com. cppreference.com更好.

迭代器是指向一系列元素(例如数组或容器)中某个元素并能够使用一组运算符迭代该范围中的元素的任何对象...

简单,错误.

光标可能是:

  • 指向元素
  • 单数,并且完全不指向任何元素.

通常,奇异值用于表示:

  • 要迭代的序列结尾:vec.end()
  • 缺少元素:std::find(...).

您可以增加,有时也可以减少光标.如果这样做,通常需要一个游标才能知道何时停止.

为什么C ++使用这种表示形式?因为这就是C的工作方式,而且效果很好……尽管它很容易出错.


铁锈

尽一切努力确保安全,并青睐易于使用的API.这排除了一对游标:

  • 一对游标并不安全:您可以轻松地进行边界迭代,并且可以获得别名引用,
  • 一对游标容易出错:很容易意外地将两个不同序列中的游标配对.

为了控制边界混淆并避免对不匹配,您必须使用单个对象;因此是类似流的API.

Rust中的Iterator API让人想起Java和C#,尽管Rust通过使用Option<T>对其进行了改进,所以它提供了一个单一的方法,而不是笨拙的hasNext()/next()调用对. next()既可以使流前进,也可以用信号通知其结束.


结论

Rust和C ++都具有一种迭代元素集合的方式:

  • C ++提供了一种类似于C的方式,灵活但容易出错,
  • 铁锈提供了一种安全,但灵活性较差的现代方式.

两种语言还提供外部内部迭代:

  • 外部:用户控制迭代(调用++next()),
  • 内部:迭代器控制用户代码(请参见std::foreachIterator::foreach).

A typical example of a C++ iterator is a pointer, and can be used to point at an element in a C array like so:

int array[] = {1, 2, 3, 4};
int* begin = std::begin(array); //Starting iterator
int* end = std::end(array) //Ending iterator

for(int* i = begin; i < end; i++)
{
    std::cout << *i << ',';
}

//Prints 1, 2, 3, 4

This is simple enough. The definition of an iterator from cplusplus.com is

An iterator is any object that, pointing to some element in a range of elements (such as an array or a container), has the ability to iterate through the elements of that range using a set of operators...

This makes sense; in the above code there were two iterators (the begin and the end iterators), and it used a for loop and incremented.

In Rust, an iterator is used like this:

let vect = vec![1, 2, 3, 4];

let vect_iter = vect.iter();

What? To iterate it you do:

vect_iter.next();
vect_iter.next();

I couldn't find any exact definition of a pointer in the Rust docs, but looking at the Iterator trait, it is seems that an iterator is a wrapper for a container that enables for easier processing, by standardizing the logic in a way (if that makes sense at all).

The main questions I have are:

  1. What are the main differences?
  2. Why does Rust have iterators in this fashion and why are they expressed so differently?
  3. Are there Rust-type iterators in C++?
  4. Are there C++-type iterators in Rust?
  5. Are they called something specific? (Internal/External?)

解决方案

An iterator is a concept found in programming languages to refer to a construct which allows iterating over collections or sequences of elements. The concept is purposely vague, it's a concept! It does not prescribe any specific implementation.

To more easily distinguish C++ from Rust, I am going to use different names:

  • C++ iterators will be named cursors,
  • Rust iterators will be named streams.

Yes, those are completely arbitrary. Note that if you look at languages like Java or C#, you will find that they also use streams.


C++

First of all, don't use cplusplus.com. cppreference.com is much better.

An iterator is any object that, pointing to some element in a range of elements (such as an array or a container), has the ability to iterate through the elements of that range using a set of operators...

Simple, and wrong.

A cursor may either:

  • point to an element,
  • or be singular and point to no element at all.

In general, the singular value is used to represent:

  • the end of the sequence to iterate over: vec.end(),
  • the absence of an element: std::find(...).

You can increment, and sometimes decrement, a cursor. If you do so, you however generally need a pair of cursors to know when to stop.

Why did C++ use such a representation? Because that's how C did it, and it works pretty well... although it's error prone.


Rust

Rust endeavors to be safe and favors APIs which are easy to use. This rules out a pair of cursors:

  • a pair of cursors is not safe: you can easily iterate out of bounds, and you can obtain aliasing references,
  • a pair of cursors is error-prone: it's easy to accidentally pair off cursors from two different sequences.

In order to control bounds, aliasing and avoid pair mismatch, you have to use a single object; thus the stream-like API.

The Iterator API in Rust is reminiscent of that of Java and C#, although Rust improves upon it by using Option<T> so that instead of the clumsy hasNext()/next() call pair, it offers a single method next() which both advances the stream and may signal its end.


Conclusion

Both Rust and C++ features a way to iterate over a collection of elements:

  • C++ offers a C-like way, flexible but error-prone,
  • Rust offers a modern way, safe but less flexible.

Both languages also offer external and internal iteration:

  • External: the user controls the iteration (calls ++ or next()),
  • Internal: the iterator controls the user code (see std::foreach and Iterator::foreach).

这篇关于Rust迭代器和C ++迭代器之间的主要区别是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆