2016-12-28 7 views
1

Я прочитал the builder pattern, а затем попытался построить 2 различных строителей (Header и Request) следующим образом:Почему один не потребляющий строитель компилируется, а другой нет?

use std::ascii::AsciiExt; 

#[derive(PartialEq, Debug)] 
pub struct Headers<'a> (pub Vec<(&'a str, String)>); 

impl<'a> Headers<'a> { 
    pub fn replace(&'a mut self, name: &'a str, value:&str) -> &mut Headers<'a> { 
     self.0.retain(|&(key, _)|!name.eq_ignore_ascii_case(key)); 
     self.0.push((name, value.to_string())); 
     self 
    } 
} 

#[derive(PartialEq, Debug)] 
pub struct Request<'a> { 
    pub headers: Headers<'a>, 
} 

impl<'a> Request<'a> { 
    pub fn header(&'a mut self, name: &'a str, value:&'a str) -> &mut Request<'a> { 
     self.headers.replace(name, value); 
     self 
    } 
} 

Почему Header скомпилироваться но Request терпит неудачу с:

error[E0499]: cannot borrow `*self` as mutable more than once at a time 
    --> src/api.rs:154:9 
    | 
153 |   self.headers.replace(name, value); 
    |   ------------ first mutable borrow occurs here 
154 |   self 
    |   ^^^^ second mutable borrow occurs here 
155 |  } 
    |  - first borrow ends here 

ответ

1

У вас есть проблемы с ваши жизни: вы используете одно и то же время жизни ('a) для слишком многих разных вещей, так что, когда компилятор пытается использовать одно время жизни для всех этих 'a, вы получите сообщение об ошибке.

Решение прост: не используйте 'a везде, где вы можете положить всю жизнь, но только там, где это необходимо.

Нет необходимости в использовании &'a mut self, экземпляр (self) не должен обладать таким значением, которое имеет течение &str. (и на самом деле это не может быть реально):

impl<'a> Headers<'a> { 
    pub fn replace(&mut self, name: &'a str, value: &str) -> &mut Headers<'a> { 
     self.0.retain(|&(key, _)|!name.eq_ignore_ascii_case(key)); 
     self.0.push((name, value.to_string())); 
     self 
    } 
} 

impl<'a> Request<'a> { 
    pub fn header(&mut self, name: &'a str, value: &str) -> &mut Request<'a> { 
     self.headers.replace(name, value); 
     self 
    } 
} 
+0

Фактически вы также можете избавиться от второго значения времени жизни 'a on value! –

+0

@ DanielWorthington-Bodart: Действительно, я пропустил это. –

Смежные вопросы