following code带有完整的类型注释:

fn enter<'a, F, R>(x: &'a i32, func: F) -> R
where
    F: for<'b> FnOnce(&'b i32) -> R,
{
    func(x)
}

fn identity<'a>(x: &'a i32) -> &'a i32 {
    x
}

fn main() {
    let x = &42;
    enter(x, identity);
}

编译器在编译时报告错误:

error[E0308]: mismatched types
  --> src/main.rs:14:5
   |
14 |     enter(x, identity);
   |     ^^^^^^^^^^^^^^^^^^ one type is more general than the other
   |
   = note: expected trait `for<'b> FnOnce<(&'b i32,)>`
              found trait `for<'a> FnOnce<(&'a i32,)>`
note: the lifetime requirement is introduced here
  --> src/main.rs:3:35
   |
3  |     F: for<'b> FnOnce(&'b i32) -> R,
   |                                   ^

For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to previous error

我的理解是,性状界限for<'b> FnOnce(&'b i32) -> Ridentity的签名for<'a> fn(&'a i32) -> &'a i32更一般,所以它应该通过.

然而,通用-> R似乎是停止编译的罪魁祸首,但我不知道为什么.

我注意到有类似的问题,但他们遇到了错误,因为他们的类型没有完全注释,编译器错误地推断了类型.

相关:

推荐答案

我的理解是,特征界限for<'b> FnOnce(&'b i32) -> R比身份的签名for<'a> fn(&'a i32) -> &'a i32更一般,所以它应该通过.

不,不是.当声明R时,'b不在上下文中,因此它不能依赖于它(这是看待这一点的一种方式,还有其他方式).

对于像std::thread::LocalKey::with()这样的API来说,这是necessary:如果允许R包含生存期(在with()的情况下是隐式的),则对线程本地的引用可以避开闭包和with(),然后在不同的线程上使用,从而导致UB.

据我所知,没有办法拥有泛型返回类型并允许它引用参数.

Rust相关问答推荐

为什么在Rust struct 中只允许最后一个字段具有动态大小的类型

阻止websocket中断的中断中断的终端(操作系统错误4)

在rust中如何修改一个盒装函数并将其赋回?

包含嵌套 struct 的CSV

如何提高自定义迭代器的`extend`性能

如何获取Serde struct 的默认实例

如何正确地将App handler传递给Tauri中的其他模块?

在Rust中声明和定义一个 struct 体有什么区别

不同类型泛型的映射

是否可以使用Serde/Rust全局处理无效的JSON值?

在 Rust 中,在需要引用 self 的 struct 体方法中使用闭包作为 while 循环条件

Rust 如何将链表推到前面?

为什么这段 Rust 代码会在没有递归或循环的情况下导致堆栈溢出?

简单 TCP 服务器的连接由对等重置错误,mio 负载较小

如何在 Rust 中按 char 对字符串向量进行排序?

Rust 将特性传递给依赖项

更好的方法来模式匹配带有 Rust 的窥视孔装配说明窗口?

当我不满足特征界限时会发生什么?

Rust,我如何正确释放堆分配的内存?

当值是新类型包装器时,对键的奇怪 HashMap 生命周期要求