gpt4 book ai didi

types - 无法为字节切片实现更高等级的生命周期类型绑定(bind)

转载 作者:行者123 更新时间:2023-11-29 07:48:17 27 4
gpt4 key购买 nike

我正在尝试在 &'a [u8] 上实现一个特征,并在使用更高等级生命周期的实现中使用它,例如:

pub trait IntoTest<'a, T> {
fn into_test(&'a self) -> T where Self: Sized;
}

impl<'a> IntoTest<'a, &'a [u8]> for &'a [u8] {
fn into_test(&'a self) -> &'a [u8] {
self
}
}

fn higher_ranked_lifetime<T>(test: T) where T: for<'a> IntoTest<'a, &'a [u8]> {
let _t = test.into_test();
}

fn main() {
println!("Hello, world!");
let vec = vec![1u8];
let slice = &vec[..];
higher_ranked_lifetime(slice);
}

短网址:http://is.gd/1QKhYk

我得到的错误是:

<anon>:19:5: 19:27 error: the trait `for<'a> IntoTest<'a, &'a [u8]>` is not implemented for the type `&[u8]` [E0277]
<anon>:19 higher_ranked_lifetime(slice);

我应该怎么做?这甚至是正确的做法吗?我不想将我的 higher_ranked_lifetime 限定在特定的生命周期内,但它适用于传递给它的任何 byte slice 。

最佳答案

这不是正确的方法,编译器是正确的。

要了解为什么会这样,一种方法是同时查看类型(切片)和您认为它实现的特征:

for<'a> IntoTest<'a, &'a [u8]>
&'a [u8]

在这里,为了清楚起见,我在切片上添加了一个生命周期参数。您可以看到在特征中绑定(bind)了生命周期参数 'abound通过 for限定符,换句话说,这个声明是自包含的,它不依赖于外部范围内的任何东西。

然而,在切片中,生命周期参数 'a 自由 - 它在某些外部范围内定义,例如,通过生命周期省略。因此,切片根本无法满足您的特征实现。为了让它发挥作用,你的特质应该像这样实现:

impl<'a, 'b> IntoTest<'a, &'a [u8]> for &'b [u8] {
fn into_test(&'a self) -> &'a [u8] {
unimplemented!()
}
}

哪个compiles ,尽管它没有也不能做你想做的事。您可以看到,在此声明中,切片的生命周期和特征签名中的生命周期是不相交的,因此切片现在确实满足 for<'a>。基于绑定(bind)。

还有另一种方式来看待这个问题。 T: for<'a> IntoTest<'a, &'a [u8]>绑定(bind)意味着类型 T为特征的每个可能的生命周期参数实现特征,因此函数本身可以决定它想要的生命周期。例如,它可以请求 'static .但很自然地在你的代码中 &[u8]绑定(bind)到 main 方法中的向量,不能是 'static .因此违反了健全性-这&[u8]无法提供用户想要的任何生命周期,因此它不会实现 for<'a> IntoTest<'a, &'a [u8]> .

请注意,仅向泛型函数添加生命周期参数也不起作用:

fn higher_ranked_lifetime<'a, T>(test: T) where T: IntoTest<'a, &'a [u8]> {
let _t = test.into_test();
}

会出现这样的错误:

<anon>:12:14: 12:18 error: `test` does not live long enough
<anon>:12 let _t = test.into_test();
^~~~
<anon>:11:79: 13:2 note: reference must be valid for the lifetime 'a as defined on the block at 11:78...
<anon>:11 fn higher_ranked_lifetime<'a, T>(test: T) where T: IntoTest<'a, &'a [u8]> {
<anon>:12 let _t = test.into_test();
<anon>:13 }
<anon>:11:79: 13:2 note: ...but borrowed value is only valid for the scope of parameters for function at 11:78
<anon>:11 fn higher_ranked_lifetime<'a, T>(test: T) where T: IntoTest<'a, &'a [u8]> {
<anon>:12 let _t = test.into_test();
<anon>:13 }

这又是正确的。请记住,您的特质是这样定义的:

pub trait IntoTest<'a, T> {
fn into_test(&'a self) -> T where Self: Sized;
}

在这里你需要self通过引用传递,其生命周期与特征的生命周期参数相同。但是,上面泛型函数的声明使得这个方法原则上是不可调用的:

fn higher_ranked_lifetime<'a, T>(test: T) where T: IntoTest<'a, &'a [u8]>

这里指定特征的生命周期参数等于函数的生命周期参数。然而,test参数本身仅存在于函数体中。因此,对 test 的任何引用,包括调用 into_test() 时的隐式:

let _t = (&test).into_test();

的生命周期将严格小于生命周期参数,因此它不能用作 into_test() 的参数。方法。这正是错误的原因。

因为你没有说明你真正需要什么,所以很难说你应该做什么。我想最通用的方法之一就是将生命周期参数放在特征上并使特征方法接受 self按值,并相应地修复通用函数:

pub trait IntoTest<T> {
fn into_test(self) -> T;
}

impl<'a> IntoTest<&'a [u8]> for &'a [u8] {
fn into_test(self) -> &'a [u8] {
self
}
}

fn higher_ranked_lifetime<'a, T>(test: T) where T: IntoTest<&'a [u8]> {
let _t = test.into_test();
}

fn main() {
println!("Hello, world!");
let vec = vec![1u8];
let slice = &vec[..];
higher_ranked_lifetime(slice);
}

does work因为现在 trait 本身没有任何生命周期参数,也没有添加任何关于如何调用它的要求。生命周期参数现在已移至实现它的类型。

关于types - 无法为字节切片实现更高等级的生命周期类型绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32197330/

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