rust - 如何将具有 `Read`特征的字符串形式的东西传递给 `From`的实现?

标签 rust borrow-checker

我正在编写一个标记器,为方便起见,我编写了一个Reader对象,该对象一次返回一个单词。当words耗尽时,它会从BufReader读取以填充words。因此,我认为filewords都应该存在于该结构中。
我遇到的问题是我想通过传递要标记化的字符串来测试它,而不必依赖文件。这就是为什么我尝试同时在FromFile&str上实现String的原因。后两个不起作用(如下所示)。
我试图用生命周期注释Reader,然后将其用于From<&'a str>的实现,但这没有用。我最终得到了Reader<'a, T: Read>,但是编译器提示没有任何东西使用了lifetime参数。From<&'static str>的替代实现效果很好,但是这意味着在静态生存期中必须存在任何传入的字符串。
我也看到了这个question/answer,但是似乎有所不同,因为他们的Enum具有有效期参数。
标题中有两个补充问题以及我的总体问题:

  • 我也看到了FromStr,但是还没有尝试使用它-是否合适?
  • 我的代码注释对下面的变量所有权/生存期是否正确?

  • 我的最小示例在这里(省略了导入):
    #[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的签名将其移入了函数,并且该函数无法返回属于局部变量的字节。您可以为&String实现它,但随后也可以使用&str

    关于rust - 如何将具有 `Read`特征的字符串形式的东西传递给 `From`的实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63646567/

    相关文章:

    error-handling - 有没有办法在任意 `.backtrace()` 特征对象上获取 SNAFU 的 `&dyn std::error::Error`?

    rust - 在无法进行类型推断时使用.into()之类的通用特征方法

    multithreading - 为什么 Rust 会阻止多重可变引用?

    algorithm - 有没有更好的方法来使用图像 0.18 crate 实现中点圆算法?

    collections - 有什么方法可以允许移动具有借入元素但不能删除它的容器?

    rust - 解包时无法移出共享引用背后的值

    rust - 如何避免对 libssl.so.10 和 libcrypto.so.10 的依赖

    generics - Rust:为什么不存储类型时泛型会继承大小大小?

    hashmap - 不能将变量借用为可变的,因为在构建自引用 HashMap 时它也被借用为不可变的

    rust - 为什么在使用 `flat_map` 时需要收集到向量中?