这是一个二人组。
理想情况下,我想实现 FromStr 特性,但不管有没有它,我都需要实现 from_str()。
CqlString 由一个 u16(两个 u8)后跟原始字符串的原始字节组成。
下面的版本会生成“错误:'bytes' 的生命周期不够长”,所以这是问题 #1。
如果我将其设置为“为 CqlString 实现 FromStr”,那么我会得到一个较早的错误:
错误:方法 from_str
具有不兼容的特征类型:预期具体生命周期,找到绑定(bind)生命周期参数 [E0053]
那么鉴于 CqlString 的结构,我该如何正确地实现 FromStr fn?
#[repr(C, packed)]
pub struct CqlString<'a>(&'a [u8]);
impl<'a> CqlString<'a> {
fn from_str(s: &str) -> Option<CqlString> {
let mut bytes = Vec::<u8>::new();
bytes.push_all(unsafe{Utils::raw_byte_repr(&s.len().to_u16())}); //convert the hashmap length to a a two byte short and start building our &[u8]
bytes.push_all(s.as_bytes());
let cqls = CqlString(bytes[]);
Some(cqls)
}
}
最佳答案
简短的回答是你不能。 CqlString
包含对其他数据的引用,但 FromStr
期望创建一个不再需要引用 &str
的完全拥有的对象。这两个概念是不相容的。
我能看到的最接近的是您可以创建一个 OwnedCqlString
:
struct OwnedCqlString {
data: Vec<u8>,
}
impl OwnedCqlString {
fn as_cql_string(&self) -> CqlString { CqlString(self.data.as_slice()) }
}
impl FromStr for OwnedCqlString {
fn from_str(s: &str) -> Option<OwnedCqlString> {
// logic here
}
}
fn main() {
let ocs: OwnedCqlString = "hello".parse();
let cs = ocs.as_cql_string();
}
最终,这归结为两个问题:
- 你打算在哪里存储代表大小的字节?
- 你如何确保那些字节紧接在内存中的字符串数据之前?
另一种想法
如果您不需要存储 byte slice ,而是可以有一个“流”接口(interface),那么您可以直接在 &str
上实现它:
trait WriteCqlStr {
fn write_to<W>(&self, &mut W)
where W: Writer;
}
impl WriteCqlStr for CqlStr {
// Straight-forward impl, write the bytes we refer to
}
impl<'a> WriteCqlStr for &'a str {
// Write the length, then write the bytes of the str
}
关于rust - 为自定义 &[u8] 类型实现 FromStr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27723433/