rust - vector 的借用引用的生命周期与其包含的借用指针之间有什么关系?

标签 rust rust-obsolete

Editor's note: This code example is from a version of Rust prior to 1.0 and is not syntactically valid Rust 1.0 code. Updated versions of this code produce different errors, but the answers still contain valuable information.

我在 Rust 0.6 中试过这段代码:

fn test<'r>(xs: &'r [&str]) -> &'r str {
    return xs[0];
}

我认为这种类型签名的意思是:“测试采用一个借用的指针,其生命周期为 'r,指向指向字符串的借用指针向量,并返回一个指向字符串的借用指针,其生命周期为 'r。但是编译器说:

refs.rs:2:8: 2:12 error: mismatched types: expected `&'r str` but found `&str` (lifetime mismatch)
refs.rs:2       return xs[0];
                       ^~~~
refs.rs:1:39: 3:1 note: the lifetime &'r  as defined on the block at 1:39...
refs.rs:1 fn test<'r>(xs: &'r [&str]) -> &'r str {
refs.rs:2       return xs[0];
refs.rs:3 }
refs.rs:1:39: 3:1 note: ...does not necessarily outlive the anonymous lifetime #1 defined on the block at 1:39
refs.rs:1 fn test<'r>(xs: &'r [&str]) -> &'r str {
refs.rs:2       return xs[0];
refs.rs:3 }
error: aborting due to previous error

这似乎暗示向量中的指针可能不会与(只读)向量本身一样长。这可能吗?

我是否需要做一些额外的注释来告诉编译器这是可以的?

同样,拥有指针的向量呢?例如

fn test<'r>(xs: &'r [~str]) -> &'r str {
    return xs[0];
}

同样,我希望能够借用一个指向向量元素的指针,至少只要我借用了整个列表。

对于上下文,我最初的问题是尝试使用拥有的指针列表扩展借用点的列表:

fn extend<'r>(xs: ~[&'r str], ys: &'r [~str]) -> ~[&'r str]

计划是:创建一个包含所有借用指针的扩展列表,使用它,然后释放扩展列表,然后释放拥有指针的原始列表,包括包含的字符串。

最佳答案

test 的第二个版本,拥有/唯一的字符串确实有效,只是必须协助编译器将 ~str 转换为 &' r str:

fn test<'r>(xs: &'r [~str]) -> &'r str {
    let tmp: &'r str = xs[0];
    tmp
}

之所以可行,是因为 xs 向量拥有它包含的 ~str,因此编译器知道它们的生命周期至少是向量的生命周期(因为在存在像这样的借用时,它也会注意可变性,因此永远不能从向量中删除字符串)。唯一的问题是说服编译器将 xs[0] 强制为一个切片,这是最容易由临时执行的。


extend 可能类似于:

fn extend<'r>(xs: ~[&'r str], ys: &'r [~str]) -> ~[&'r str] {
    let mut xs = xs;
    for vec::each(ys) |s| {
        let tmp: &'r str = *s;
        xs.push(tmp)
    }
    xs
}

似乎 vec::each(ys) 有效,但 ys.each 无效,这可能是一个错误(我正在调查现在我打开了#6655)。

如果你想就地修改一个vector,通常的方法是传递一个可变的引用给vector,即

fn extend<'r>(xs: &mut ~[&'r str], ys: &'r [~str]) {
    for vec::each(ys) |s| {
        let tmp: &'r str = *s;
        xs.push(tmp)
    }
}

它被称为 extend(&mut vec, additions)


举例说明:

rusti> let a = &[~"a", ~"b", ~"c"];
()
rusti> test(a)
"a"
rusti> extend(~["1", "2", "3"], a)
~["1", "2", "3", "a", "b", "c"]

关于rust - vector 的借用引用的生命周期与其包含的借用指针之间有什么关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16646997/

相关文章:

rust - 要求关联的错误类型实现 Debug 特性是一种好习惯吗?

arrays - 使用常量表达式声明数组的大小

rust - 如何遍历盒装迭代器?

rust - 什么是已弃用的 std::raw::Repr 的现代模拟?

rust - &T 和 T/&, ~T 和 T/~ 的区别

rust - 如何知道迭代器的当前位置?

sorting - 为什么这种部分快速排序实现比标准库排序慢得多?

arrays - 如何创建一个静态字符串数组?

enums - 如何在 Rust 中参数化枚举器?

rust - 为什么我在这个例子中得到 "Borrowed value does not live long enough"?