首页 文章

如何强制将值从内部范围移动到外部而不是借用?

提问于
浏览
2

我是Rust的新手 . 如何强制将值从内部范围移动到外部而不是借用?

let mut r_buf = BufReader::new(file.unwrap());
let mut eof = false;

while !eof {
    let piece = r_buf.fill_buf();
    if piece.is_ok() {
        let mut piece = piece.unwrap();
        let piece_len = piece.len();

        if opt.compress {
            let deflated = deflate_bytes(piece);
            if deflated.is_none() {
                panic!(format!("Cant deflate file {}", path.to_str().unwrap_or("")));
            }

            let deflate_unwrapped = deflated.unwrap();
            let deflate_deref = deflate_unwrapped.deref();
            piece = deflate_deref;
        }
        /* bf: &mut BufStream<File>*/
        let w = bf.write(piece);

        if w.is_ok() {
            written_bytes = w.unwrap();
        }

我无法将 &[u8]deflate_deref 移动到 piece . 我试过 Vec<u8>Box<&[u8]> . 我有一个错误"deflate_unwrapped does not live long enough" ...我不能通过 [u8] 类型操作,因为它在编译类型中没有确切的大小,而引用我只能借用...

在这种情况下,我必须使用特定的东西或重写此代码吗?

游乐场链接http://is.gd/u8wfm7

1 回答

  • 8

    让我们将您的代码减少到一个真正最小的例子:

    fn main() {
        let a = {
            let b = 42;
            &b
        };
    }
    

    因为这就是你的情况所追求的:尝试在原始对象超出范围之后对某些东西进行引用并存储该引用 .

    有两种主要方法可以解决这个问题:

    • 更改要引用的变量的范围:
    fn main() {
        let b;
        let a = {
            b = 42;
            &b
        };
    }
    

    只要您不处理跨越函数边界(即,返回对函数内部内容的引用)或某些与循环边界的组合,这通常是最佳解决方案 .

    • 不要参考,而是做你当时想做的处理:
    fn main() {
        let a = {
            let b = 42;
            b.clone()
        };
    }
    

    在您的特定情况下,这可能会将 &[u8] 转换为 Vec<u8> ,可以写成 Vec::from(slice) . 当然,在您的具体示例中,您仍然需要担心以第一种方式将向量存储在某处,或者使用 Cow<[u8]> 来表示整个事物 .

    我写了一篇文章,除其他事项外,还考虑了一些您可能会发现有用的问题:http://chrismorgan.info/blog/rust-fizzbuzz.html . 它涉及 Stringstr ,你在处理 Vec<u8> / Bytes[u8] ,但概念非常相似 .

相关问题