Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Generics 特性上的链接功能_Generics_Rust_Lifetime_Nightly Build - Fatal编程技术网

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))
}