首页 > 解决方案 > 在 Rust 中,如何解决编译错误无法返回临时值?

问题描述

我正在尝试将一些简短的 python 代码转换为 Rust。它有一个主要的递归函数。

但是我被困在粘贴代码底部附近发生的以下错误中。对于我的情况,阅读相同错误号的答案似乎很难解释。请给出一些提示来修复错误。

cannot return value referencing temporary value

returns a value referencing data owned by the current functionrustc(E0515)
lib.rs(91, 63): temporary value created here
lib.rs(94, 11): returns a value referencing data owned by the current function

[游乐场][2]

use std::collections::HashMap;
#[derive(Eq,PartialEq,Clone,Debug)]       
pub struct TokImmuta<'a>{
   tl:Vec<&'a str>,iops:&'a HashMap<&'a str,(Option<usize>,usize)>       
} 
#[derive(Eq,PartialEq,Copy,Clone,Debug)]       
pub struct TokMuta<'a>{
   length:usize,pos:Option<usize>,current:&'a str       
}



   
pub fn LBP<'a>(immuta:&TokImmuta<'a>,t:&str)->Option<usize>{return immuta.iops[t].0;} 
pub fn RBP<'a>(immuta:&TokImmuta<'a>,t:&str)->usize{return immuta.iops[t].1;} 


pub fn newTok2<'a>(ts:&'a str,iops:&'a mut HashMap<&'a str,(Option<usize>,usize)>)->( TokMuta<'a>,TokImmuta<'a>){     
   let tl:Vec<&str>=ts.split(" ").collect();
   let tl_len=tl.len();
   iops.insert("$END",(None,0));
    
    (  
       TokMuta{          
         length : tl_len,
         pos : None,
         current : "$BEGIN",
      },
      TokImmuta{
         tl :  tl,     
         iops : iops,         
       },
   )
}
pub fn Next<'a>(muta:&mut TokMuta<'a>,immuta:&TokImmuta<'a>)->&'a str{              
    if muta.current == "$PRE" {
       assert!(muta.pos!=None);
        muta.current = immuta.tl[muta.pos.unwrap()];
    }
    else if immuta.iops.contains_key(muta.current)
                          && RBP(immuta,muta.current)  == 100{
            muta.current = "$POST"
         }
    else {
        muta.pos=if muta.pos==None{Some(0)}else{Some(muta.pos.unwrap() + 1)};
        if muta.pos.unwrap() >= muta.length {
            muta.current = "$END"
        }
        else {
            let atok = immuta.tl[muta.pos.unwrap()];
            let lbp_atok=LBP(immuta,atok);
            if immuta.iops.contains_key(atok) && (lbp_atok!=None && lbp_atok.unwrap() == 100) {
                muta.current = "$PRE";
            }
            else {
                muta.current = atok;
            }
        }
    }
    return muta.current;
    }
pub fn TokSeq<'a>(muta:&mut TokMuta<'a>,immuta:TokImmuta<'a>)->String{            
    let mut s = muta.current.to_string();          
    while &muta.current != &"$END"{
       s = format!("{} {}",s,Next(muta,&immuta));
    }
    return s.to_string()
}


//=====================================
use std::rc::Rc;
#[derive(Debug)]
pub struct Sexp<'a>{op:&'a str,left:Eexp<'a>,right:Eexp<'a>}
#[derive(Debug)]
pub enum Eexp<'a>{S(&'a str),C(Rc<Sexp<'a>>)}
//=====================================


pub fn parseExpr<'a>(tok:&'a mut TokMuta<'a>,immuta:&TokImmuta<'a>,minrbp:usize)->Eexp<'a>{      
   let mut s = Eexp::S(Next(tok, &immuta));                
   let mut n = Next(tok, &immuta);                
   
   loop  {        
      
      let tok_lbp_n= if let Some(xxx)=LBP(&immuta,n){xxx as isize}else{-1}; 
      if (minrbp as isize) >= tok_lbp_n { break }
      s=Eexp::C(Rc::new(Sexp{op:n,left:s,right:parseExpr(&mut tok.clone(),immuta,RBP(&immuta,n))}));
      n = tok.current.clone() ;
   }          
////////////////////////////////////////////////////////////////////
//ERROR
////////////////////////////////////////////////////////////////////
   return s                      
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
}
pub fn PL2LL(pl:Eexp)->String {                   
   let s =match pl{
   Eexp::C(rc)=> {
               
      format!("( {} {:#?} {:#?} )",rc.op,rc.left,rc.right)                  

标签: rust

解决方案


看起来您正在克隆,然后立即将克隆的 ref 传递给parseExpr. 在那种情况下,您是否考虑过将所有权转移tok给该方法而不是传递一个可变的 ref,因为无论如何您都在克隆它?

基本改变

pub fn parseExpr<'a>(tok:&'a mut TokMuta<'a>, immuta:&TokImmuta<'a>,minrbp:usize)

pub fn parseExpr<'a>(mut tok: TokMuta<'a>, immuta:&TokImmuta<'a>,minrbp:usize)      

并更新呼叫站点。

锈游乐场


推荐阅读