2017-07-08 26 views
4

此代碼:爲什麼在一個模式守衛中使用可變性借款?

fn t(r: &[u8]) { 
    match r { 
     _ if r.iter().any(|&x| x == b';') => {} 
     _ => {} 
    } 
} 

給我的錯誤:

error[E0301]: cannot mutably borrow in a pattern guard 
    | 
10 |   _ if r.iter().any(|&x| x == b';') => {} 
    |    ^^^^^^^^ borrowed mutably in pattern guard 

我明白,我不能在匹配模式性情不定地借錢,但爲什麼編譯器認爲r.iter()借用性情不定地?可變的借款有一個單獨的方法iter_mut

我怎樣才能檢查&[u8]包含b';'而不引入單獨的功能?

回答

5

該錯誤消息是有點更細緻 - iter不性情不定地借用,但iter結果被性情不定地借來的。這是因爲Iterator::any通過可變引用需要self

fn any<F>(&mut self, f: F) -> bool 
where 
    F: FnMut(Self::Item) -> bool, 

這裏的再現:

struct X; 

impl X { 
    fn new() -> X { X } 
    fn predicate(&mut self) -> bool { true } 
} 

fn main() { 
    match() { 
     _ if X::new().predicate() => {} 
     _ => {} 
    } 
} 

我剛剛檢查,如果切片contains值:

fn t(r: &[u8]) { 
    match r { 
     _ if r.contains(&b';') => {} 
     _ => {} 
    } 
} 

實際上,這是借款檢查員過分侵略的一個例子即從比賽門衛的「外面」突然借用一些東西是一個不好的主意,但可變的借用在比賽後衛中創造的東西應該是安全的。

當借用檢查器被重寫爲使用Rust的MIR圖層時,這種特殊情況很可能會起作用。

參見:

+0

是否有意義的迭代器::任何通過可變引用採取自我? – user12341234

+2

@ user12341234是的,它的確如此。你必須能夠改變迭代器以調用next,它會更新迭代器的內部狀態,以便每次調用都可以返回不同的內容。 – Shepmaster

相關問題