2015-02-02 4 views
3

У меня есть некоторый код, который выглядит следующим образом:Доступ к последнему элементу Vec или кусочек

trait Stack { 
    fn top(&mut self) -> Option<f64>; 
} 

impl Stack for Vec<f64> { 
    fn top(&mut self) -> Option<f64> { 
     match self.pop() { 
      None => None, 
      Some(v) => { 
       self.push(v); 
       Some(v) 
      } 
     } 
    } 
} 

fn main() { 
    let mut stack: Vec<f64> = Vec::new(); 
    stack.push(5.3); 
    stack.push(2.3); 
    stack.push(1.3); 

    match stack.top() { 
     Some(v) => println!("Top of the stack: {}", v), 
     None => println!("The stack is empty"), 
    } 
} 

Сейчас метод top() модифицирует self, но я думаю, что это не должно быть необходимыми. Очевидный способ сделать это на самом деле не работает:

fn top(&mut self) -> Option<f64> { 
    match self.len() { 
     0 => None, 
     n => self[n - 1], 
    } 
} 

Я играл вокруг немного с преобразованием usize в i32 и обратно, но ни один из того, что я пишу не выглядит коротким и читаемым, как я думаю, должно.

ответ

5

И только после размещения вопроса, ответ кажется очевидным:

fn top (&mut self) -> Option<&f64> { 
    match self.len() { 
     0 => None, 
     n => Some(&self[n-1]) 
    } 
} 

Т.е. usize никогда не было проблемой - возвращаемый тип top() был.

10

Вы также можете использовать slice::last:

fn top(&mut self) -> Option<f64> { 
    self.last().cloned() 
} 

Option::cloned используется для преобразования из Option<&f64> к Option<f64>, соответствие желаемой функции подписи.

Вы также можете удалить mut как из определения реализации, так и из определения.

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