如何将具有 Read 特征的 string-like 传递给 From 的实现?
How can I pass something string-like with the `Read` trait to an implementation of `From`?
我正在编写分词器,为了方便起见,我写了一个 Reader
object,returns 一次一个词。当 words
耗尽时,它从 BufReader
中读取以填充 words
。因此,我认为 file
和 words
都应该存在于结构中。
我遇到的问题是我想通过传递要标记化的字符串来测试它,而不是必须依赖文件。这就是为什么我尝试在 File
、&str
和 String
上实现 From
。后两个不起作用(如下突出显示)。
我试图用一生来注释 Reader
,然后我在 From<&'a str>
的实现中使用了它,但那没有用。我最终得到了 Reader<'a, T: Read>
,但编译器抱怨说没有使用生命周期参数。
From<&'static str>
的替代实现工作正常,但这意味着传入的任何字符串都必须在静态生命周期内存在。
我也看到了这个,但是好像不一样,因为他们的Enum
有生命周期参数。
我有两个补充问题以及标题中的整体问题:
- 我也看到了
FromStr
,但还没有尝试使用它 - 它适合这个吗?
- 下面我的代码注释变量 ownership/lifetimes 是否正确?
我的最小示例在这里(省略了导入):
#[derive(Debug)]
struct Reader<T: Read> {
file: BufReader<T>,
words: Vec<String>,
}
impl From<File> for Reader<File> {
fn from(value: File) -> Self { // value moves into from
Reader::new(BufReader::new(value)) // value moves into BufReader(?)
}
}
// THE NEXT TWO DON'T WORK
impl From<&str> for Reader<&[u8]> {
fn from(value: &str) -> Self { // Compiler can't know how long the underlying data lives
Reader::new(BufReader::new(value.as_bytes())) // The data may not live as long as BufReader
}
}
impl From<String> for Reader<&[u8]> {
fn from(value: String) -> Self { // value moves into from
Reader::new(BufReader::new(value.as_bytes())) // value doesn't move into BufReader or Reader
} // value gets dropped
}
impl<T: Read> Reader<T> {
fn new(input: BufReader<T>) -> Self {
Self {
file: input,
words: vec![],
}
}
}
&str
编译时带有生命周期注解 (playground):
impl<'a> From<&'a str> for Reader<&'a [u8]> {
fn from(value: &'a str) -> Self {
Reader::new(BufReader::new(value.as_bytes()))
}
}
如评论中所述,您只需要注释引用,而不是尝试将生命周期注释合并到 Reader
本身。
请注意,相同的方法对 String
不起作用,因为 from
的签名将其移入函数中,并且该函数不能 return 属于本地的字节多变的。您可以为 &String
实施它,但您也可以使用 &str
.
我正在编写分词器,为了方便起见,我写了一个 Reader
object,returns 一次一个词。当 words
耗尽时,它从 BufReader
中读取以填充 words
。因此,我认为 file
和 words
都应该存在于结构中。
我遇到的问题是我想通过传递要标记化的字符串来测试它,而不是必须依赖文件。这就是为什么我尝试在 File
、&str
和 String
上实现 From
。后两个不起作用(如下突出显示)。
我试图用一生来注释 Reader
,然后我在 From<&'a str>
的实现中使用了它,但那没有用。我最终得到了 Reader<'a, T: Read>
,但编译器抱怨说没有使用生命周期参数。
From<&'static str>
的替代实现工作正常,但这意味着传入的任何字符串都必须在静态生命周期内存在。
我也看到了这个Enum
有生命周期参数。
我有两个补充问题以及标题中的整体问题:
- 我也看到了
FromStr
,但还没有尝试使用它 - 它适合这个吗? - 下面我的代码注释变量 ownership/lifetimes 是否正确?
我的最小示例在这里(省略了导入):
#[derive(Debug)]
struct Reader<T: Read> {
file: BufReader<T>,
words: Vec<String>,
}
impl From<File> for Reader<File> {
fn from(value: File) -> Self { // value moves into from
Reader::new(BufReader::new(value)) // value moves into BufReader(?)
}
}
// THE NEXT TWO DON'T WORK
impl From<&str> for Reader<&[u8]> {
fn from(value: &str) -> Self { // Compiler can't know how long the underlying data lives
Reader::new(BufReader::new(value.as_bytes())) // The data may not live as long as BufReader
}
}
impl From<String> for Reader<&[u8]> {
fn from(value: String) -> Self { // value moves into from
Reader::new(BufReader::new(value.as_bytes())) // value doesn't move into BufReader or Reader
} // value gets dropped
}
impl<T: Read> Reader<T> {
fn new(input: BufReader<T>) -> Self {
Self {
file: input,
words: vec![],
}
}
}
&str
编译时带有生命周期注解 (playground):
impl<'a> From<&'a str> for Reader<&'a [u8]> {
fn from(value: &'a str) -> Self {
Reader::new(BufReader::new(value.as_bytes()))
}
}
如评论中所述,您只需要注释引用,而不是尝试将生命周期注释合并到 Reader
本身。
请注意,相同的方法对 String
不起作用,因为 from
的签名将其移入函数中,并且该函数不能 return 属于本地的字节多变的。您可以为 &String
实施它,但您也可以使用 &str
.