rust中使用變數的途徑有三種,所有權(ownership), 不可變引用(immutable reference) 和可變引用(mutable reference)。如果學習了rust,我們會發現這三種使用值的辦法充斥著rust的角角落落。在此,我們來研究一下rust iterator,及其與這三種方式的聯絡。
首先,所有的迭代器都實現了iterator trait
,而next
方法無疑是iterator trait
中最基本的方法。我們來看下它的方法簽名:
pub trait iterator
來自:
我們可以看到,next
方法的引數是&mut self
,也就是可變的迭代器引用
。因此,callnext
方法的型別一定是乙個可變的迭代器,不可變迭代器不能callnext
方法。
next
方法的返回值是option
這個enum
,目的是可以讓我們判斷是否有next value
。如果有下乙個值,那麼返回值就是some
,如果沒有下乙個值,那麼返回值就是none
。我們可以通過match
來判斷。
現在我們來看vec
生成迭代器的辦法。有三種方式可以實現這個目的,分別是iter
,iter_mut
和into_iter
。根據我的理解,這三種方法分別需要vec
的&self
,&mut self
和self
,即向量的不可變引用,可變引用和向量的所有權。當然了,需要所有權的方法,會move
原向量的所有權,所以原向量不再能夠使用。
這三個方法生成的迭代器有什麼區別呢?根據我的理解,就是在實現iterator trait
的時候,這三種迭代器的associated type
,即關聯型別不一樣。這就會導致呼叫next
方法的時候:
iter
返回的是值的不可變引用,即&t
iter_mut
返回的是可變引用,即&mut t
into_iter
返回的是t
型別的值
讓我們來寫**驗證我們的猜想。首先來看into_iter
:
let v = vec![string::from("good")];
for mut i in v.into_iter() ",i);
}println!("",v);
3 | for mut i in v.into_iter() ",v);
| ^ value borrowed here after move
通過報錯資訊我們可以看到,v
的所有權已經被move
了,不再擁有向量的所有權。如果我們注釋掉最後一句,則可以正常使用。因為我們用mut i
來代表mut string
,所以我們可以改變string
的值。
let v = vec![string::from("good")];
for mut i in v.into_iter() ",i);
}
good morning
let v = vec![1];
for i in v.iter()
通過assert_eq!
這個巨集,我們可以驗證,i
就是&1
。
let v = vec![1];
for i in v.into_iter()
而通過assert_eq!
這個巨集,我們可以驗證,此時i
是1
。
let mut v = vec![1];
for i in v.iter_mut()
println!("",v);
這段**的執行結果是:
[555]
實際上,根據我們的分析,這裡的i
的型別是&mut i32
,所以解引用之後可以改變其值。同時,iter_mut
只需要&mut self
而不是所有權,所以後面還可以正常使用v
。 程序 三種型別,三種狀態
一 程序的概念 程序是執行乙個程式時所分配的資源,資源包括占用的cpu,記憶體等,是乙個動態執行過程。二 程序的組成 正文段使用者資料段 系統資料段 程序控制塊 pcb cpu暫存器值 堆疊 三 程序控制塊pcb 程序控制塊是系統用來控制和管理程序,獲得程序狀態和程序存在特徵的唯一標識。包括 程序標...
MYSQL inserOrUpdate三種寫法
一般資料表中都會不允許插入重複資料,先查詢資料庫中資料,再判斷是否存在,比較麻煩,可以直接用sql語句解決這個問題 1 insert into on duplicate key 無則新增,有則更新 insert into customer code name address createtime v...
Linux三種網路 vmware三種網路模式
nat 網路位址轉換 預設使用vmnet8 原理 nat是network address translate的簡稱 nat計數應用在internet閘道器和路由器上,比如192.168.0.123這個位址要訪問internet,它的資料報就要通過乙個閘道器或者路由器,而閘道器或者路由器擁有乙個能訪問...