亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

iter和into_iter有什么區別?

iter和into_iter有什么區別?

Git
慕碼人2483693 2019-11-12 14:02:28
我正在做具有示例代碼片段的Rust by Example教程:// Vec examplelet vec1 = vec![1, 2, 3];let vec2 = vec![4, 5, 6];// `iter()` for vecs yields `&i32`. Destructure to `i32`.println!("2 in vec1: {}", vec1.iter()     .any(|&x| x == 2));// `into_iter()` for vecs yields `i32`. No destructuring required.println!("2 in vec2: {}", vec2.into_iter().any(| x| x == 2));// Array examplelet array1 = [1, 2, 3];let array2 = [4, 5, 6];// `iter()` for arrays yields `&i32`.println!("2 in array1: {}", array1.iter()     .any(|&x| x == 2));// `into_iter()` for arrays unusually yields `&i32`.println!("2 in array2: {}", array2.into_iter().any(|&x| x == 2));我非常困惑-對于Vec從iteryields引用返回的迭代器和從into_iteryields值返回的迭代器,但是對于數組,這些迭代器是相同的嗎?這兩種方法的用例/ API是什么?
查看完整描述

3 回答

?
慕工程0101907

TA貢獻1887條經驗 獲得超5個贊

第一個問題是:“什么是into_iter?”


into_iter來自IntoIterator特征:


pub trait IntoIterator 

where

    <Self::IntoIter as Iterator>::Item == Self::Item, 

{

    type Item;

    type IntoIter: Iterator;

    fn into_iter(self) -> Self::IntoIter;

}

當您要指定如何將特定類型轉換為迭代器時,可以實現此特征。最值得注意的是,如果類型實現IntoIterator,則可以在for循環中使用它。


例如,Vec實施IntoIterator……三次!


impl<T> IntoIterator for Vec<T>

impl<'a, T> IntoIterator for &'a Vec<T>

impl<'a, T> IntoIterator for &'a mut Vec<T>

每個變體都略有不同。


這個消耗,Vec并且它的迭代器產生值(T直接):


impl<T> IntoIterator for Vec<T> {

    type Item = T;

    type IntoIter = IntoIter<T>;


    fn into_iter(mut self) -> IntoIter<T> { /* ... */ }

}

另外兩個通過引用獲取向量(在兩種情況下都不要被into_iter(self)因為self是引用的簽名所欺騙),并且它們的迭代器將生成對內部元素的引用Vec。


這產生了不可變的參考:


impl<'a, T> IntoIterator for &'a Vec<T> {

    type Item = &'a T;

    type IntoIter = slice::Iter<'a, T>;


    fn into_iter(self) -> slice::Iter<'a, T> { /* ... */ }

}

雖然這產生了可變的參考:


impl<'a, T> IntoIterator for &'a mut Vec<T> {

    type Item = &'a mut T;

    type IntoIter = slice::IterMut<'a, T>;


    fn into_iter(self) -> slice::IterMut<'a, T> { /* ... */ }

}

所以:


iter和之間有什么區別into_iter?


into_iter是獲取迭代器的通用方法,無論該迭代器產生值,不可變引用還是可變引用都是上下文相關的,有時可能令人驚訝。


iter并且iter_mut是臨時方法。這可以解決上下文相關位,并且按照慣例,您可以獲取一個迭代器,該迭代器將產生引用。


Rust by Example帖子的作者舉例說明了對依賴于所into_iter調用的上下文(即類型)的依賴而產生的驚奇,并且還通過使用以下事實使問題更加復雜:


IntoIterator未針對[T; N],僅針對&[T; N]和實現&mut [T; N]

如果沒有為值實現方法,則會自動搜索該值的引用

這是非常令人驚訝的,into_iter因為所有類型(除外[T; N])都為所有3個變體(值和引用)實現了它。數組不可能實現產生值的迭代器,因為它不能“縮小”以放棄其項。


關于數組為何實現IntoIterator(以一種令人驚訝的方式):使得有可能在循環中遍歷對它們的引用for。


查看完整回答
反對 回復 2019-11-12
?
一只甜甜圈

TA貢獻1836條經驗 獲得超5個贊

.into_iter()不是針對數組本身實現的,而僅針對&[]。相比:


impl<'a, T> IntoIterator for &'a [T]

    type Item = &'a T


impl<T> IntoIterator for Vec<T>

    type Item = T

由于IntoIterator僅在上定義&[T],因此切片本身無法像Vec使用值那樣被丟棄。(值不能移出)


現在,為什么是這樣,這是一個不同的問題,我想學習一下自己。推測:數組是數據本身,切片只是對其的視圖。實際上,您不能將數組作為值移動到另一個函數中,只能傳遞它的視圖,因此也不能在那里使用它。


查看完整回答
反對 回復 2019-11-12
  • 3 回答
  • 0 關注
  • 1718 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號