代码
示例代码(稳定版Rust 1.45.0,2018版)无需外部库。
type Error = Box<dyn std::error::Error>;
type Result<R=()> = std::result::Result<R, Error>;
struct Arena;
pub trait AsSized<'a> {
type AsSized: Sized + 'a;
}
impl<'a, T: Sized + 'a> AsSized<'a> for T {
type AsSized = Self;
}
impl<'a, T: AsSized<'a>> AsSized<'a> for [T] {
type AsSized = &'a [T::AsSized];
}
pub trait Format<T>: Send + Sync
where T: ?Sized
{
fn get_bytes<'a>(&self, value: &'a T, arena: &'a Arena) -> Result<&'a [u8]>;
fn get_value<'a>(&self, bytes: &'a [u8], arena: &'a Arena) -> Result<T::AsSized>
where T: AsSized<'a>;
}
struct RawBytes;
impl Format<[u8]> for RawBytes
where [u8]: for<'a> AsSized<'a, AsSized=&'a [u8]>
{
fn get_bytes<'a>(&self, value: &'a [u8], _arena: &'a Arena) -> Result<&'a [u8]> {
Ok(value)
}
fn get_value<'a>(&self, bytes: &'a [u8], arena: &'a Arena) -> Result<<[u8] as AsSized<'a>>::AsSized> {
Ok(bytes)
}
}
问题
我在RawBytes
的get_value
实现中遇到了编译错误:
error[E0195]: lifetime parameters or bounds on method `get_value` do not match the trait declaration
我不理解问题出在哪里。两个定义之间的生命周期规范似乎是相同的。那么我应该如何编写RawBytes
的get_value
的实现,以使其正常工作?
我认为由于u8: Sized
,所以<u8 as AsSized<'a>>::AsSized = u8
,然后<[u8] as AsSized<'a>>::AsSized = &'a [u8]
,但似乎情况并非如此?
背景
Format
使用基于arena的分配器将字节片转换为复杂类型,并从中进行转换。我计划为各种Serde格式编写适配器。 RawBytes
是一个针对字节片的Format
的微不足道的实现,它只返回原始片。
Format
的两种方法都允许返回从输入值借用的值。格式本身可以在线程之间共享,因此self的寿命与返回值的寿命无关。
AsSized
的目的是允许直接使用动态大小的类型,例如str
和[u8]
,但由于动态大小的类型无法直接返回,AsSized
为任何类型提供了一个大小等效的类型;动态大小的类型返回指向DST的引用(从arena借用)。可以直接返回的有大小的类型,其AsSized
类型为self。
还尝试过
fn get_value<'a>(&self, bytes: &'a [u8], arena: &'a Arena) -> Result<'a [u8]>
我尝试将impl的
get_value
简化为直接命名切片;然后Rust表示get_value
的实现完全丢失。fn get_value<'a>(&self, bytes: &'a [u8], arena: &'a Arena) -> Result<&'a [<u8 as AsSized<'a>>::AsSized]>
这会产生相同的“lifetime parameters... do not match”错误。