Rust 如何将元组(String,String)上的迭代器转换为(&;str,&;str)的迭代器?

Rust 如何将元组(String,String)上的迭代器转换为(&;str,&;str)的迭代器?,rust,lifetime,Rust,Lifetime,从(String,String)的迭代器转换为(&str,&str)的迭代器时遇到问题。我正在使用外部库,因此无法更改该库的签名,也不确定是否需要更改。基本上我有这个函数def: 使用超链接; fn构建url(&mut self,pairs:I) //其中I:迭代器 url.set\u查询\u来自\u对( 参数映射(|x:(字符串,字符串)|-> (&str,&str){let(ref k,ref v)=x;(k,v)}); } 但我有一个可怕的错误:错误:“x.0”的寿命不够长 我认为let

(String,String)
的迭代器转换为
(&str,&str)
的迭代器时遇到问题。我正在使用外部库,因此无法更改该库的签名,也不确定是否需要更改。基本上我有这个函数def:

使用超链接;
fn构建url(&mut self,pairs:I)
//其中I:迭代器
url.set\u查询\u来自\u对(
参数映射(|x:(字符串,字符串)|->
(&str,&str){let(ref k,ref v)=x;(k,v)});
}
但我有一个可怕的错误:
错误:“x.0”的寿命不够长

我认为let中的
ref
关键字在这里应该是正确的,即使用迭代器保留所有权,只需进行借用。如果我在let中去掉
ref
,将let更改为以下内容,我会遇到类似的问题:

let (k, v) = x; (&k, &v)

那么
k
v
活得不够长。有人建议修复此问题吗?

您不能让迭代器(安全地)生成对任何内部或所有状态的引用;
迭代器
特性就是不允许它。这些类型的构造通常被称为“流迭代器”,它们目前在语言/stdlib中有点像一个漏洞

考虑
(String,String)
值流经
map
调用时会发生什么。每个元组都从
I::next
返回,这将导致所有权传递到您给
map
的闭包中。因此,在闭包中使用
ref
时,引用的是闭包的局部变量。现在构造一个新元组,返回它并。。。因为闭包拥有
字符串
s(它们存储在
k
v
中),所以它们被销毁,从而使您尝试返回的引用无效

问题是无法避免获得
(String,String)
项目的所有权

现在,已经说过了,你可以在这里作弊。您所需要做的就是确保
(String,String)
值在迭代器中的每个单独步骤之外继续存在。因此:

let params: Vec<_> = params.collect();
url.set_query_from_pairs(params.iter().map(|&(ref x, ref y)| (&x[..], &y[..])))
let-params:Vec=params.collect();
url.set_query_from_pairs(params.iter().map(|和(ref x,ref y)|(&x[…],&y[…]))

这是因为
Vec::iter
为我们提供了
迭代器
,我们可以从迭代器中借用,而无需取得所有权(由
params
保留).

由于您的
params
参数是从
Vec
创建的,因此您可以将where子句更改为
where I:Iterator
并通过调用

your_vector.iter().map(|(a, b)|, (&a[..], &b[..])))
一个简化的例子:

fn测试
{
因为它里面有{
倾倒区;
}
}
fn转储(s:&str){
println!(“{}”,s);
}
fn main(){
设v=vec![“a.”to_string(),“42.”to_string();
测试(v.iter().map(|s |和s[…]);
}

您需要的是流式迭代器。这些还不可能。但可能还有另一种选择。您从哪里获得
params
迭代器?它是地图还是矢量?如果是这样,您可以从中创建一个非所有权迭代器,然后将其映射到
(&str,&str)
iteratories,它实际上来自一个vec![]创建,这样我就可以更改该参数类型…我不熟悉&x[…]是否有文档记录?我不记得我在书中或其他参考资料中读到过它。这对我来说很有用:
url.set_query_from_pairs(params.iter().map(|&(ref k,ref v)|->(&'a str,&'a str){(k,v)})说得很清楚,我将我的方法签名切换为使用&'a Vec,然后将映射中的&str绑定到该生存期。@bluejekyll,
&x[…]
就是我们所说的切片语法
x[…]
是一种索引操作,它采用
FullRange
对象(
)-对于
字符串
,它意味着返回对应于整个字符串的
str
。然后使用
&
获取
&str
。您还可以编写例如
&x[1..]
来将字符串从第二个字节切到最后。描述了此语法。您的方法由于deref强制而起作用-
k
v
&String
s,并且在已知目标类型(
&str
)的特定上下文中,
&String
可以自动转换为
&str