具有相同参数和结果类型的两个fn类型中的TypeId在非一般函数中采用TypeId与用相同类型实例化的一般函数中采用TypeId不同:

在这个rust程序(permalink)中,虽然&dyn I(第4行)和&T(第12行)打印相同的TypeId,但当这些字体被包装成fn类型时,打印的TypeId是不同的(第5行和第13行).

use std::any::TypeId;

fn main() {
    dbg!(TypeId::of::<&dyn I>());
    dbg!(TypeId::of::<fn(&dyn I)>());
    f::<dyn I>();
}

trait I {}

pub fn f<T: ?Sized + 'static>() {
   dbg!(TypeId::of::<&T>());
   dbg!(TypeId::of::<fn(&T)>());
}

我的目标是能够在Any对象中存储fn个指针,以便稍后我可以向下投射它们.但这不起作用(大概是因为TypeId不匹配).

推荐答案

问题是dyn I的隐式派生生命周期不同,对于fn(&dyn I),也分配给引用的未命名生命周期'_,对于f::<dyn I>,因为您将类型参数限制为T: 'static,因此推断为'static,因此TypeId::of的两个参数实际上是不同的类型fn(&'_ (dyn I + '_))fn(&'_ (dyn I + 'static))

我认为该功能不可能将要求放宽到(dyn I + '_),因此您必须对裸版本更加严格:

use std::any::TypeId;
#[test]
fn same_type() {
    let bare = TypeId::of::<fn(&(dyn I + 'static))>();
    let call = f::<dyn I>();
    assert_eq!(bare, call);
}

pub fn f<T: ?Sized + 'static>() -> TypeId {
    TypeId::of::<fn(&T)>()
}

trait I {}

Rust相关问答推荐

Rust kill std::processs::child

是否可以为`T:Copy`执行`T. clone`的测试

如何在Bevy/Rapier3D中获得碰撞机的计算质量?

如何删除Mac Tauri上的停靠图标?

铁 rust 中的泛型:不能将`<;T作为添加>;::Output`除以`{Float}`

异步函数返回的future 生存期

在Rust中克隆源自INTO_ITER()的迭代器的成本?

Rust ndarray:如何从索引中 Select 数组的行

Tokio';s io::用Cursor拆分<;Vec<;u8>>;赢得';t get the full writted data

Rust 中的复合 `HashSet` 操作或如何在 Rust 中获得 `HashSet` 的显式差异/并集

存储返回 impl Trait 作为特征对象的函数

Sized问题的动态调度迭代器Rust

Rust 程序中的内存泄漏

Rust 中的生命周期:borrow 的 mut 数据

使用 traits 时,borrow 的值不会存在足够长的时间

为什么在 macOS / iOS 上切换 WiFi 网络时 reqwest 响应会挂起?

为什么我可以同时传递可变和不可变引用?

如何获得对数组子集的工作可变引用?

我可以在不调用 .clone() 的情况下在类型转换期间重用 struct 字段吗?

相交着色器从 SSBO 中读取零