在类型别名上调用静态方法

问题描述

在使用盒装闭包时,我遇到了以下问题:

type Test = Rc<dyn Fn() -> i64>;

fn test_bad() -> Test {
    Test::new(|| 42)
}

fn test_good() -> Test {
    Rc::new(|| 42)
}

在第一种情况下,我使用类型别名来引用 new 方法,而在第二种情况下我直接使用 Rc

在第一种情况下,编译器抱怨:

    |       Test::new(|| 42)
    |             ^^^ function or associated item not found in `Rc<(dyn Fn() -> i64 + 'static)>`
    |
    = note: the method `new` exists but the following trait bounds were not satisfied:
            `dyn Fn() -> i64: Sized`

但第二种情况工作得很好。有人可以解释一下区别吗?有什么办法可以通过类型别名来引用 new 还是我需要自己包装它?

解决方法

test_good 中,通过在 Rc::new 上调用 || 42,您不会创建一个 Rc<dyn Fn() -> i64>,而是一个 Rc<ClosureType> ,其中 ClosureTypeunique type of the closure provided,它 大小。然后,由于 Rc<ClosureType> 在返回 Rc<dyn Fn() -> i64> 的函数中返回,因此它隐式地将其强制转换为 trait 对象。

test_bad 失败,因为它不是从构造一个大小闭包的 Rc 然后将它转换为一个未大小的 trait 对象的 Rc,而是试图直接构造一个 {{1 }} 一个未定义大小的 trait 对象,由于函数的所有参数都必须设置大小,因此失败。

我认为没有通过类型别名引用 Rc 的直接方法,尽管您可以很容易地创建自己的:

new
,

泛型类型别名有效,但具体类型别名失败:

> d1
             date sym  dir Qty newColName
    1: 2019-10-29  A1   up   9          9
    2: 2019-10-29  A1 down   1          9
    3: 2019-10-29  A1 down  11          9
    4: 2019-10-29  A1   up   2         11
    5: 2019-10-29  A1   up   3         14

当您调用 use std::rc::Rc; type MyGenericRc<T> = Rc<T>; // works fn construct_with_generic_alias() -> MyGenericRc<dyn Fn() -> i64> { MyGenericRc::new(|| 42) } type MyConcreteRc = Rc<dyn Fn() -> i64>; // fails fn construct_with_concrete_alias() -> MyConcreteRc { MyConcreteRc::new(|| 42) } 时,编译器会选择 MyGenericRc::new(<closure>) 作为要使用的具体函数实现,因为 Rc::<closure type>::new(<closure>) 需要一个 Rc::new 参数并且每个匿名闭包类型都是 { {1}}。但是,在调用该函数后,编译器执行大小强制转换,将返回的 Sized 转换为 Sized

当您调用 Rc<anonymous closure type> 时,您不会让编译器决定使用哪个 Rc<dyn Fn() -> i64> 实现,而是告诉它必须使用 MyConcreteRc::new(<closure>) 但不可能满足该实现的类型要求因为 Rc::new 需要一个 Rc::<dyn Fn() -> i64>::new 参数,而 newSized,因此您会看到编译错误消息。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...