[英]Error when passing Rc as a function argument
将Rc<dyn Trait>
作为函数参数传递时,我面临一些奇怪的行为。 下面的代码演示了这个问题。
use std::rc::Rc;
trait Trait {}
struct Struct {}
impl Trait for Struct {}
fn function(_t: Rc<dyn Trait>) {}
fn main() {
let n = Rc::new(Struct {});
// ok
let r = Rc::clone(&n);
function(r);
// error, why?
// function(Rc::clone(&n));
}
如果我将Rc
存储在临时变量中,则一切正常。 但是,如果我尝试在函数调用中直接调用Rc::clone
则会出现以下错误。
|
19 | function(Rc::clone(&n));
| ^^ expected trait object `dyn Trait`, found struct `Struct`
|
= note: expected reference `&std::rc::Rc<dyn Trait>`
found reference `&std::rc::Rc<Struct>`
Struct
实现Trait
。 为什么我会收到这个错误?
这基本上只是类型推断规则的一个皱纹。 为了调用Rc::clone(&n)
,编译器必须知道Rc
的类型参数是什么。
let r = Rc::clone(&n);
function(r);
在第一行,编译器看到Rc::clone
是用&Rc<Struct>
类型的参数调用的。 它可以为r
自由选择类型,因此它推断被调用的函数应该是Rc::<Struct>::clone
并且r
也是Rc<Struct>
。 移到下一行,调用function(r)
只是将r
强制转换为Rc<dyn Trait>
。
function(Rc::clone(&n));
这里编译器再次必须为Rc
选择一个类型参数,但它没有完全的自由:它必须选择可以传递给function
东西。 所以它假设类型参数是dyn Trait
,因为Rc<dyn Trait>
是function
期望的。
但是,您不能调用Rc::<dyn Trait>::clone(&n)
,因为虽然Rc<Struct>
可以被强制为Rc<dyn Trait>
,但强制不能通过引用传递(您不能强制&Rc<Struct>
到&Rc<dyn Trait>
)。 所以强制不能在Rc::clone(...)
调用中发生。
您可以通过使用 turbofish 将类型参数指定为Struct
来编译单行版本:
function(Rc::<Struct>::clone(&n));
或者通过添加显式强制转换来暗示编译器它不应该从它作为function
参数的位置推断类型:
function(Rc::clone(&n) as _);
n.clone()
也有效,因为.
对类型参数毫无疑问:它总是会找到Rc::<Struct>::clone
因为自动解引用只查看接收器类型( n
的类型)而不关心表达式的上下文。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.