使用as_slice()时,“borrowed value does not live long enough”

14

我遇到了一个错误:

extern crate rustc_serialize; // 0.3.24

use rustc_serialize::base64::{self, FromBase64, ToBase64};

fn main() {
    let a: [u8; 30] = [0; 30];
    let b = a.from_base64().unwrap().as_slice();
    println!("{:?}", b);
}

错误:

error[E0597]: borrowed value does not live long enough
 --> src/main.rs:7:13
  |
7 |     let b = a.from_base64().unwrap().as_slice();
  |             ^^^^^^^^^^^^^^^^^^^^^^^^           - temporary value dropped here while still borrowed
  |             |
  |             temporary value does not live long enough
8 |     println!("{:?}", b);
9 | }
  | - temporary value needs to live until here
  |
  = note: consider using a `let` binding to increase its lifetime

对我来说,代码没有错,但是为什么会出现这个错误?


2
注意,let a: [u8, ..30] = [ 123, 34, ... ]; 这种写法可能会很麻烦,因为每次改变数组时都需要调整长度。如果你希望记录长度,那么这样做是可以的;但如果你不需要并且感到困扰,还有另一种表达方式:let a = [123u8, 34, ...]; 关键在于 12334 只是通用的整数(没有具体类型),所以通过指定 u8 来限制它们;然而,由于数组是同质容器,另一种解决方案是限制其中一个元素的类型(通常是第一个元素,即 123u8),编译器会推断出所有元素都是 u8 - Matthieu M.
1个回答

19

这里的问题在于您没有把 from_base64 的结果存储在任何地方,然后通过调用 as_slice 来获取引用。像这样链接调用会导致 from_base64 的结果在该行结束时退出作用域,取出的引用将不再有效。

extern crate rustc_serialize; // 0.3.24

use rustc_serialize::base64::FromBase64;

fn main() {
    let a: [u8; 30] = [0; 30];
    let b = a.from_base64().unwrap();
    println!("{:?}", b.as_slice());
}

7
问题在于你没有将 from_base64 的结果存储在任何地方,然后通过调用 as_slice 获取其引用。为什么会出现这种情况呢?在几乎任何其他编程语言中都可以这样做并且可以正常工作。 - Incerteza
1
这就是目前的情况,RFC31将解决这个问题。 - Arjan
那么即使 a.from_base64() 不改变 a 并且生成一个新的变量,但在 Rust 中现在还没有实现这个功能? - Incerteza
它与 a 没有任何关联,只是一个事实,你获取了对 from_base64 结果的引用,该结果是临时的,因为它没有被存储在任何地方。 - Arjan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接