Rust 泛型特征实现中的生命周期
我想创建一个类似于以下结构的特性(我的特定用例稍微复杂一些,但这抓住了我遇到的问题和错误)。我的问题是上一次impl的生命周期。我想我需要把它们挤进特质的定义中,但我不知道怎么做。我怎样才能整理出生命周期,这样就可以编译了Rust 泛型特征实现中的生命周期,rust,lifetime-scoping,Rust,Lifetime Scoping,我想创建一个类似于以下结构的特性(我的特定用例稍微复杂一些,但这抓住了我遇到的问题和错误)。我的问题是上一次impl的生命周期。我想我需要把它们挤进特质的定义中,但我不知道怎么做。我怎样才能整理出生命周期,这样就可以编译了 trait-MyTrait{ fn-f(f:f,x:Self)->兜售 哪里 F:Fn(TIn)->TOut; } 为T{ FNF(f:f,x:T)->兜售 哪里 F:Fn(T)->兜售, { f(x) } } impl-MyTrait for&T 哪里 T:克隆, { f
trait-MyTrait{
fn-f(f:f,x:Self)->兜售
哪里
F:Fn(TIn)->TOut;
}
为T{
FNF(f:f,x:T)->兜售
哪里
F:Fn(T)->兜售,
{
f(x)
}
}
impl-MyTrait for&T
哪里
T:克隆,
{
fn f(f:f,x:T)->兜售
哪里
F:Fn(T)->兜售,
{
f(x.clone())
}
}
//此impl无法编译:
为T{
FNF(f:f,x:T)->兜售
哪里
F:Fn&T)->兜售,
{
f&x
}
}
我认为您的最后一个特性无法编译,因为它本质上是不安全的
您的impl实际上相当于:
impl for T
这意味着,对于任何类型的T
和任何生存期'a
,T
实现MyTrait
。所以我可以这样写:
fn foo(x:&'static i32)->&'static i32{
x
}
fn main(){
设sp:&'static i32={
Fn(&r TIn)->兜售;
严格来说,这比特质更具共性
我认为你能安全地写这篇文章的唯一方法是这样:
impl for T{
FNF(f:f,x:T)->兜售
哪里
F:Fn(&'T)->兜售,
{
f(…)
}
}
但这可能不是您想要的,因为您不能使用x
作为参数。
请注意,您甚至需要使T:'static
,以使其完全安全。类型签名
impl<T> MyTrait<&T> for T {
fn f<TOut, F>(f: F, x: T) -> TOut
where
F: Fn(&T) -> TOut,
{
}
}
您可以将F
上的边界向上移动()
trait-MyTrait
哪里
F:Fn(锡)->兜售,
{
fnf(f:f,x:Self)->兜售;
}
为T
哪里
F:Fn(T)->兜售,
{
FNF(f:f,x:T)->兜售{
f(x)
}
}
impl-MyTrait for&T
哪里
T:克隆,
F:Fn(T)->兜售,
{
fn f(f:f,x:T)->兜售{
f(x.clone())
}
}
为T
哪里
F:Fn&T)->兜售,
{
FNF(f:f,x:T)->兜售{
f&x
}
}
Making'static
缩小了实现的范围,impl MyTrait@ÖmerErden:这是我的第一个想法,但是失败了,错误信息相同。我认为我上面的崩溃代码与这个impl一样可以使用。我认为我需要更改trait和impl。在我看来,非编译implld可以作为一个独立的函数来编写(看起来你同意吗?),所以我的问题只是调整trait,使其涵盖所有三种用法。也许我需要为trait添加一个life参数?
impl<'a, T: 'a> MyTrait<&'a T> for T {
fn f<TOut, F>(f: F, x: T) -> TOut
where
F: for<'r> Fn(&'r T) -> TOut,
{
}
}
impl<'a, T: 'a> MyTrait<&'a T> for T {
fn f<TOut, F>(f: F, x: T) -> TOut
where
F: Fn(&'a T) -> TOut,
{
}
}
impl<'a, T: 'a> MyTrait<&'a T> for T {
fn f<TOut, F>(f: F, x: T) -> TOut
where
F: Fn(&'a T) -> TOut,
{
//panic!(); or
f(unsafe { &*(&x as *const T) })
}
}
println!("{:?}", String::f(|x: &String| x, "aa".to_string()));
trait MyTrait<TIn, F, TOut>
where
F: Fn(TIn) -> TOut,
{
fn f(f: F, x: Self) -> TOut;
}
impl<T, F, TOut> MyTrait<T, F, TOut> for T
where
F: Fn(T) -> TOut,
{
fn f(f: F, x: T) -> TOut {
f(x)
}
}
impl<T, F, TOut> MyTrait<T, F, TOut> for &T
where
T: Clone,
F: Fn(T) -> TOut,
{
fn f(f: F, x: &T) -> TOut {
f(x.clone())
}
}
impl<T, F, TOut> MyTrait<&T, F, TOut> for T
where
F: Fn(&T) -> TOut,
{
fn f(f: F, x: T) -> TOut {
f(&x)
}
}