将 Rc 作为函数参数传递时出错

2023-11-25

我在经过时遇到一些奇怪的行为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 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

  • 创建盒装特征背后的机制是如何工作的?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 Rc 作为函数参数传递时出错 的相关文章

随机推荐