Generics 特性上的链接功能
我试图对一个特征进行可链接的转换,但我遇到了一些问题 我有一系列形式的转换函数:Generics 特性上的链接功能,generics,rust,lifetime,nightly-build,Generics,Rust,Lifetime,Nightly Build,我试图对一个特征进行可链接的转换,但我遇到了一些问题 我有一系列形式的转换函数: fn transform<T: MyTrait>(in: T) -> impl MyTrait 我已经写了这个函数 fn chain<T, U, F>(val: Box<T>, f: F) -> Box<MyTrait> where T: MyTrait, U: MyTrait, F: FnOnce(T) ->
fn transform<T: MyTrait>(in: T) -> impl MyTrait
我已经写了这个函数
fn chain<T, U, F>(val: Box<T>, f: F) -> Box<MyTrait>
where T: MyTrait,
U: MyTrait,
F: FnOnce(T) -> U {
Box::new(f(*val))
}
因此,除非转换函数可以接受a&t或a&mut,否则此设计无法工作(因为我需要使用输入来生成输出,所以它不能接受a&t或a&mut)。完整的编译器消息是:
error[E0310]:参数类型'U'可能寿命不够长
--> :7:3
|
7 |方框::新(f(*val))
| ^^^^^^^^^^^^^^^^^
|
=帮助:考虑添加一个显式的生命周期绑定“u:‘static’…
注意:…以便类型'U'满足其所需的生存期限制
--> :7:3
|
7 |方框::新(f(*val))
| ^^^^^^^^^^^^^^^^^
错误:由于上一个错误而中止
编译器说它需要U
在的静态生命周期内生存;这实际上意味着它内部的任何引用都必须在该生命周期内有效,因为框
可以永远存在(据编译器所知)
因此,解决方法很简单:将静态
添加到U
的边界:
fn chain<T, U, F>(val: Box<T>, f: F) -> Box<MyTrait>
where T: MyTrait,
U: MyTrait + 'static,
F: FnOnce(T) -> U,
{
Box::new(f(*val))
}
fn链(val:Box,f:f)->Box
其中T:MyTrait,
U:MyTrait+'静态,
F:FnOnce(T)->U,
{
方框::新(f(*val))
}
添加一个额外的U:“static
也将是等效的。我很困惑,T
和U
应该是不同的特征吗?@Jsor:可能吧,因为F
在这里是一个转换器。@MatthieuM。我认为他们实际上想在同一个trait的两个实现之间进行转换,然后将其转换为一个装箱的trait对象。@Jsor:啊,对不起;我看错了。考虑到链的类型,我认为T
和U
只是相同特征的不同实例,因为链本身接收一个特征并返回相同的特征。说U:MyTrait+'static,
可能比引入第二行U
更快。是的,我考虑过了,但武断地决定,添加seaprate边界更为清晰。我要补充一点。我不认为这更清楚,因为用第二行描述类型参数(因此乍一看可能不太清楚)似乎很少见好吧,就是这么简单;)但是,现在还有另一个问题:在链
内部,框
指向一个未大小的特征,因此我无法将其传递给转换函数,也无法传递对它的引用。。。我想我必须彻底而简单地抛弃这个想法,让变换函数接受并返回一个框
。
let mut val: Box<MyTrait> = ...;
//here we can know the type inside the Box
if ... {
val = chain(val, transform);
}
//but here we don't know anymore
//(its either the original type,
//or the type returned by transform)
fn chain<T, U, F>(val: Box<T>, f: F) -> Box<MyTrait>
where T: MyTrait,
U: MyTrait + 'static,
F: FnOnce(T) -> U,
{
Box::new(f(*val))
}