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
。