Tho*_*ard 5 rust rust-obsolete
编者注:此代码示例来自 Rust 1.0 之前的版本,在语法上不是有效的 Rust 1.0 代码。此代码的更新版本会产生不同的错误,但答案仍包含有价值的信息。
我在 Rust 0.6 中尝试过这段代码:
fn test<'r>(xs: &'r [&str]) -> &'r str {
return xs[0];
}
Run Code Online (Sandbox Code Playgroud)
我认为这种类型签名的意思是:“test 使用一个借用的指针,生命周期为 'r,指向字符串借用指针的向量,并返回一个指向字符串的借用指针,生命周期也为 'r。但是编译器说:
fn test<'r>(xs: &'r [&str]) -> &'r str {
return xs[0];
}
Run Code Online (Sandbox Code Playgroud)
这似乎意味着向量中的指针可能没有(只读)向量本身那么长。这可能吗?
我需要做一些额外的注释来告诉编译器这是可以的吗?
同样,拥有指针的向量呢?例如
fn test<'r>(xs: &'r [~str]) -> &'r str {
return xs[0];
}
Run Code Online (Sandbox Code Playgroud)
同样,只要我借用了整个列表,我希望能够借用指向向量元素的指针。
对于上下文,我最初的问题是尝试使用拥有的指针列表扩展借用点列表:
fn extend<'r>(xs: ~[&'r str], ys: &'r [~str]) -> ~[&'r str]
Run Code Online (Sandbox Code Playgroud)
计划是:创建一个包含所有借用指针的扩展列表,使用它,然后释放扩展列表,然后释放拥有指针的原始列表,包括包含的字符串。
的第二个版本test,具有拥有/唯一字符串确实有效,只是必须协助编译器将 转换~str为 a &'r str:
fn test<'r>(xs: &'r [~str]) -> &'r str {
let tmp: &'r str = xs[0];
tmp
}
Run Code Online (Sandbox Code Playgroud)
这样做的原因是xs向量拥有~str它所包含的s,因此编译器知道它们的生命周期至少是向量的生命周期(因为它也小心存在这样的借用的可变性,所以字符串永远不能从向量中删除)。唯一的问题是说服编译器强制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
}
Run Code Online (Sandbox Code Playgroud)
看起来可行vec::each(ys),但ys.each不可行,这可能是一个错误(我现在正在调查它,我打开了#6655)。
如果要就地修改向量,通常的方法是将可变引用传递给向量,即
fn extend<'r>(xs: &mut ~[&'r str], ys: &'r [~str]) {
for vec::each(ys) |s| {
let tmp: &'r str = *s;
xs.push(tmp)
}
}
Run Code Online (Sandbox Code Playgroud)
这被称为 like 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"]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2265 次 |
| 最近记录: |