这基本上只是类型推断规则中的一个小问题。为了打电话Rc::clone(&n)
,编译器必须知道参数的类型Rc
is.
let r = Rc::clone(&n);
function(r);
在第一行,编译器看到Rc::clone
使用类型参数调用&Rc<Struct>
。它可以自由选择类型r
,所以它推断被调用的函数应该是Rc::<Struct>::clone
and r
也是Rc<Struct>
。移动到下一行,调用function(r)
just coerces r
to Rc<dyn Trait>
.
function(Rc::clone(&n));
这里编译器再次必须选择一个类型参数Rc
,但它没有完全的自由:它必须选择可以传递给的东西function
。所以它假设类型参数是dyn Trait
, since Rc<dyn Trait>
是什么function
期望。
但是,您不能调用Rc::<dyn Trait>::clone(&n)
,因为虽然Rc<Struct>
可以被强迫Rc<dyn Trait>
, 强制不能通过引用传递(你不能强迫&Rc<Struct>
to &Rc<dyn Trait>
)。所以强制不能在内部发生Rc::clone(...)
call.
您可以通过将类型参数指定为来编译单行版本Struct
使用涡轮鱼:
function(Rc::<Struct>::clone(&n));
或者通过暗示编译器不应该从其作为参数的位置推断出类型function
,通过添加显式强制转换:
function(Rc::clone(&n) as _);
n.clone()
也有效,因为方法解析过程.对类型参数没有任何疑问:它总是会找到Rc::<Struct>::clone
因为自动解引用仅查看接收者类型(n
) 并且不关心表达式的上下文。
Related