gpt4 book ai didi

rust - 为什么在实现 From<&[u8]> 时需要生命周期

转载 作者:行者123 更新时间:2023-12-05 03:26:11 25 4
gpt4 key购买 nike

我想要一个 MyType支持 From<&[u8]>特质,但我遇到了“终身问题”:

这是一个最小可行的例子:

struct MyType {
i: i32
}

impl MyType {
fn from_bytes(_buf: &[u8]) -> MyType {
// for example...
MyType { i: 3 }
}
}

impl From<&[u8]> for MyType {
fn from(bytes: &[u8]) -> Self {
MyType::from_bytes(bytes)
}
}

fn do_smth<T>() -> T where T: From<&[u8]>
{
// for example...
let buf : Vec<u8> = vec![1u8, 2u8];
T::from(buf.as_slice())
}

(...这是一个 Rust playground link )

出于我无法理解的原因,Rust 编译器告诉我:

error[E0637]: `&` without an explicit lifetime name cannot be used here
--> src/lib.rs:17:36
|
17 | fn do_smth<T>() -> T where T: From<&[u8]>
| ^ explicit lifetime name needed here

我不是生命周期方面的专家,我不明白为什么这段代码需要生命周期。 解决此问题的最佳方法是什么?

Rust 可能认为类型 T可能是 &[u8]本身?但是,在那种情况下,生命周期应该被推断为与 From::<&[u8]>::from() 的输入相同。 , 不是吗?

给我的一个修复是:

fn do_smth<T>() -> T where for<'a> T: From<&'a [u8]>
{
// for example...
let buf : Vec<u8> = vec![1u8, 2u8];
T::from(buf.as_slice())
}

...但我不明白这个修复,也不明白为什么首先需要生命周期。

最佳答案

Rust 首先要你写:

fn do_smth<'a, T>() -> T
where
T: From<&'a [u8]>,
{
// for example...
let buf: Vec<u8> = vec![1u8, 2u8];
T::from(&buf)
}

您明确表示可以在任何生命周期 'a 和任何类型 T 中调用此函数,使得 T 实现 From<&'a [u8]>。

但是 Rust 然后提示:

error[E0597]: `buf` does not live long enough
--> src/lib.rs:24:13
|
18 | fn do_smth<'a, T>() -> T
| -- lifetime `'a` defined here
...
24 | T::from(&buf)
| --------^^^^-
| | |
| | borrowed value does not live long enough
| argument requires that `buf` is borrowed for `'a`
25 | }
| - `buf` dropped here while still borrowed

你 promise 这个函数可以在任何生命周期内工作,但事实证明这不是真的,因为在函数体中你创建了一个对本地 Vec 的新引用,它具有不同的生命周期,比如 'local.您的函数仅在“a 等于”本地时有效,但您保证它也适用于所有其他生命周期。您需要的是一种表达这些生命周期相同的方法,我认为唯一可行的方法是更改​​对参数的局部引用:

fn do_smth<'a, T>(buf: &'a [u8]) -> T
where
T: From<&'a [u8]>,
{
T::from(buf)
}

然后编译。

如果不是 promise 它可以在任何生命周期内工作的函数,而是想让调用者 promise 它可以在任何生命周期内工作,您可以改用 HRTB s 让调用者 promise 它。

fn do_smth<T>() -> T
where
for<'a> T: From<&'a [u8]>,
{
// for example...
let buf: Vec<u8> = vec![1u8, 2u8];
T::from(&buf)
}

现在,由于您可以使用任何 生命周期,因此本地生命周期也可以工作并且代码可以编译。

关于rust - 为什么在实现 From<&[u8]> 时需要生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71804597/

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