I'm trying to implement common trait for a bunch of types created from binary data (read from a disk). Majority of trait methods could use default implementations and only conversions etc. would be needed to be implemented separately. I would like to use TryFrom<&[u8]> trait for conversions from binary data to my types but I don't know how to express (in the context of trait) that lifetime of &[u8] and lifetimes of values of my types created from it are not related. Here is minimal example of the problem.
use std::convert::TryFrom;
struct Foo;
// Value of Foo can be created from &[u8] but it doesn't borrow anything.
impl TryFrom<&[u8]> for Foo {
type Error = ();
fn try_from(v: &[u8]) -> Result<Self, ()> {
Ok(Foo)
}
}
trait Bar<'a>
where
Self: TryFrom<&'a [u8], Error = ()>, // `&` without an explicit lifetime name cannot be used here
{
fn baz() -> Self {
let vec = Vec::new();
Self::try_from(&vec).unwrap() // ERROR: vec does not live long enough (nothing is borrowed)
}
}
Run Code Online (Sandbox Code Playgroud)
Alternative solution would be to make conversions as trait methods but it would be nicer to use common std traits. Is there a way to achieve this? (Or I could use const generics but I don't want to rely on nightly compiler.)
你想要的是“更高等级的特质界限”(HRTB,或者简单的“热情的男孩”)。它们看起来像这样:for<'a> T: 'a。这个例子只是意味着:“对于每一个可能的生命周期'a,T必须......”。在你的情况下:
trait Bar
where
Self: for<'a> TryFrom<&'a [u8], Error = ()>,
Run Code Online (Sandbox Code Playgroud)
您还可以直接将该要求指定为超级特征绑定而不是where子句:
trait Bar: for<'a> TryFrom<&'a [u8], Error = ()> { ... }
Run Code Online (Sandbox Code Playgroud)
是的,现在它只是意味着所有实现者都Bar必须在所有TryFrom<&'a [u8], Error = ()>可能的生命周期内实现。那就是你想要的。
| 归档时间: |
|
| 查看次数: |
1603 次 |
| 最近记录: |