为何Rust中用Borrow做本地绑定,调用RefCell的borrow()时无法推断类型?
问题原因分析
你遇到的差异源于方法解析的歧义:
borrow_mut()能正常运行:因为你没有导入std::borrow::BorrowMuttrait,编译器会自动通过Rc的Deref特性,将what(Rc<RefCell<i32>>)解引用为内部的RefCell<i32>,调用的是RefCell自身的borrow_mut()方法,返回类型RefMut<'_, i32>明确,编译器可直接推断。borrow()报错:因为你导入了std::borrow::Borrowtrait,编译器会优先把borrow()解析为trait方法。此时存在两个符合条件的实现:Rc<T>的Borrow<T>实现,以及T(即RefCell<i32>)自身的默认Borrow<T>实现,编译器无法确定你要借用的目标,因此需要明确类型注解或显式指定调用的方法。
正确的不可变借用方式
以下几种方案都可以解决问题:
方案1:显式解引用调用RefCell的borrow方法
通过*或deref()显式解引用Rc,直接调用RefCell自身的方法:
let k = Some(Rc::new(RefCell::new(5))); let what = k.as_ref().unwrap().clone(); let kk = (*what).borrow(); // 或者使用deref()方法: // let kk = what.deref().borrow();
方案2:指定变量的明确类型
给kk指定Ref<'_, i32>类型,让编译器明确你要的是RefCell的借用结果:
use std::cell::Ref; use std::cell::RefCell; use std::borrow::Borrow; use std::rc::Rc; let k = Some(Rc::new(RefCell::new(5))); let what = k.as_ref().unwrap().clone(); let kk: Ref<'_, i32> = what.borrow();
方案3:使用完全限定语法调用RefCell的borrow方法
直接指定调用RefCell的borrow方法,避免trait方法的歧义:
use std::cell::RefCell; use std::borrow::Borrow; use std::rc::Rc; let k = Some(Rc::new(RefCell::new(5))); let what = k.as_ref().unwrap().clone(); let kk = RefCell::borrow(&*what);
方案4:移除Borrow trait的导入(若代码无其他依赖)
如果你的代码不需要使用std::borrow::Borrow trait的其他功能,可以删掉对应的导入语句,编译器会自动将borrow()解析为RefCell的方法:
use std::cell::RefCell; use std::rc::Rc; let k = Some(Rc::new(RefCell::new(5))); let what = k.as_ref().unwrap().clone(); let kk = what.borrow(); // 可正常编译
内容的提问来源于stack exchange,提问作者egor10_4
相关产品推荐
相关产品推荐

