|
|
@ -1,5 +1,5 @@
|
|
|
|
# 无处不在的迭代器
|
|
|
|
# 无处不在的迭代器
|
|
|
|
Rust的迭代器无处不在,直至你在它上面栽了跟头,经过深入调查才发现:哦,原来是迭代器的锅。不信的话,看看这个报错你能想到是迭代器的问题吗: `borrow of moved value: words`.
|
|
|
|
Rust 的迭代器无处不在,直至你在它上面栽了跟头,经过深入调查才发现:哦,原来是迭代器的锅。不信的话,看看这个报错你能想到是迭代器的问题吗: `borrow of moved value: words`.
|
|
|
|
|
|
|
|
|
|
|
|
## 报错的代码
|
|
|
|
## 报错的代码
|
|
|
|
以下的代码非常简单,用来统计文本中字词的数量,并打印出来:
|
|
|
|
以下的代码非常简单,用来统计文本中字词的数量,并打印出来:
|
|
|
@ -71,7 +71,7 @@ let n = words.clone().count();
|
|
|
|
在继续之前,我得先找一个地方藏好,因为俺有一个感觉,烂西红柿正在铺天盖地的呼啸而来,伴随而来的是读者的正义呵斥:
|
|
|
|
在继续之前,我得先找一个地方藏好,因为俺有一个感觉,烂西红柿正在铺天盖地的呼啸而来,伴随而来的是读者的正义呵斥:
|
|
|
|
**你管`clone`叫最好、最`rusty`的解决方法??**
|
|
|
|
**你管`clone`叫最好、最`rusty`的解决方法??**
|
|
|
|
|
|
|
|
|
|
|
|
大家且听我慢慢道来,事实上,在Rust中`clone`不总是性能低下的代名词,因为`clone`的行为完全取决于它的具体实现。
|
|
|
|
大家且听我慢慢道来,事实上,在 Rust 中`clone`不总是性能低下的代名词,因为`clone`的行为完全取决于它的具体实现。
|
|
|
|
|
|
|
|
|
|
|
|
#### 迭代器的`clone`代价
|
|
|
|
#### 迭代器的`clone`代价
|
|
|
|
对于迭代器而言,它其实并不需要持有数据才能进行迭代,事实上它包含一个引用,该引用指向了保存在堆上的数据,而迭代器自身的结构是保存在栈上。
|
|
|
|
对于迭代器而言,它其实并不需要持有数据才能进行迭代,事实上它包含一个引用,该引用指向了保存在堆上的数据,而迭代器自身的结构是保存在栈上。
|
|
|
@ -102,6 +102,6 @@ where
|
|
|
|
以上代码实现了对`Split`迭代器的克隆,可以看出,底层的的数组`self.v`并没有被克隆而是简单的复制了一个引用,依然指向了底层的数组`&[T]`,因此这个克隆非常高效。
|
|
|
|
以上代码实现了对`Split`迭代器的克隆,可以看出,底层的的数组`self.v`并没有被克隆而是简单的复制了一个引用,依然指向了底层的数组`&[T]`,因此这个克隆非常高效。
|
|
|
|
|
|
|
|
|
|
|
|
## 总结
|
|
|
|
## 总结
|
|
|
|
看起来是无效借用导致的错误,实际上是迭代器被消费了导致的问题,这说明Rust编译器虽然会告诉你错误原因,但是这个原因不总是根本原因。我们需要一双慧眼和勤劳的手,来挖掘出这个宝藏,最后为己所用。
|
|
|
|
看起来是无效借用导致的错误,实际上是迭代器被消费了导致的问题,这说明 Rust 编译器虽然会告诉你错误原因,但是这个原因不总是根本原因。我们需要一双慧眼和勤劳的手,来挖掘出这个宝藏,最后为己所用。
|
|
|
|
|
|
|
|
|
|
|
|
同时,克隆在Rust中也并不总是**bad guy**的代名词,有的时候我们可以大胆去使用,当然前提是了解你的代码场景和具体的`clone`实现,这样你也能像文中那样作出非常`rusty`的选择。
|
|
|
|
同时,克隆在 Rust 中也并不总是**bad guy**的代名词,有的时候我们可以大胆去使用,当然前提是了解你的代码场景和具体的`clone`实现,这样你也能像文中那样作出非常`rusty`的选择。
|