T + 'a) -> ... 有没有办法(当然不安全)transmute输入函数所以,它变成i-6ren">
gpt4 book ai didi

generics - 有没有办法用不同的生命周期来表达 "same"通用类型?

转载 作者:行者123 更新时间:2023-11-29 08:07:22 25 4
gpt4 key购买 nike

考虑以下(不完整的)函数签名:

unsafe fn foo<'a, T: 'a>(func: impl FnOnce() -> T + 'a) -> ...

有没有办法(当然不安全)transmute输入函数所以,它变成impl FnOnce() -> S + 'static其中 S 与 T 的类型相同,但具有 S: 'static .

我知道可以通过使用盒装特征 ( FnBox ) 然后在盒子上调用 transmute 来改变闭包本身的生命周期边界。但是,这不会影响返回类型 ( T )。据我了解,T: 'aT: 'static就类型系统而言,它们是不同的类型。所以我想知道是否有可能用 Rust 表达这一点。

我想签名必须看起来像这样(忽略闭包本身的生命周期界限):

unsafe fn<'a, T, S>(func: impl FnOnce() -> T) -> impl FnOnce() -> S
where
T: 'a,
S: 'static`

但是如果没有 T 的说明,你怎么调用这个函数呢?和 S除了它们的生命周期之外是相同的。

免责声明我知道修改生命周期边界通常不是一个好主意,但这是用于通过其他方式强制执行生命周期限制的生成线程。

最佳答案

如果您只想对简单类型执行此操作,这会很简单,但您的尝试会遇到很多障碍。我将按照我在寻找答案时遇到的顺序进行解释。

首先,您不能使用 impl trait 来实现它类型,因为函数本身必须选择它要返回的具体实现,但它不能,因为实现将始终基于参数类型的选择 func来自来电者。这排除了“自然”类型的:

unsafe fn foo<'a, T>(func: impl FnOnce() -> T + 'a) -> impl FnOnce() -> T + 'static

并导致更像是:

unsafe fn foo<'a, T, F, G>(func: F) -> G
where
F: FnOnce() -> + 'a,
G: FnOnce() -> + 'static,

但是调用者怎么知道类型G需要是?

如果您尝试使用 mem::transmute要欺骗借用检查器,您需要告诉它要转化成什么。问题是你只知道类型是(例如)impl FnOnce() -> T + 'static ,但实际上您无法写下闭包的具体类型,因此这也行不通。

所以我认为答案是Box结果。这听起来可能不尽如人意,但情况会变得更糟!虽然可以创建 Box<dyn FnOnce()>它是 currently impossible to call that function later ,这意味着您必须做出另一个妥协,即从 FnOnce 升级至 Fn .

use std::mem;

unsafe fn foo<'a, T>(func: impl Fn() -> T + 'a) -> Box<dyn Fn() -> T + 'static> {
let boxed: Box<dyn Fn() -> T + 'a> = Box::new(func);
mem::transmute(boxed)
}

总而言之,也许您应该退后一步,找到一个不同的问题来解决,而不是这个问题。

关于generics - 有没有办法用不同的生命周期来表达 "same"通用类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52424449/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com