3 回答

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。

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使用值那樣被丟棄。(值不能移出)
現在,為什么是這樣,這是一個不同的問題,我想學習一下自己。推測:數組是數據本身,切片只是對其的視圖。實際上,您不能將數組作為值移動到另一個函數中,只能傳遞它的視圖,因此也不能在那里使用它。
- 3 回答
- 0 關注
- 1718 瀏覽
添加回答
舉報