Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust &;str_Rust_Iterator - Fatal编程技术网

Rust &;str

Rust &;str,rust,iterator,Rust,Iterator,将迭代器转换为字符串,并穿插一些常量字符串(例如“\n”)的规范方法是什么 例如,假设: let xs = vec!["first", "second", "third"]; let it = xs.iter(); 有一种方法可以生成字符串s,方法是将结果收集到一些Iterable和join中: let s = it .map(|&x| x) .collect::<Vec<&str>>() .join("\n"); s=it .

迭代器
转换为
字符串
,并穿插一些常量字符串(例如
“\n”
)的规范方法是什么

例如,假设:

let xs = vec!["first", "second", "third"];
let it = xs.iter();
有一种方法可以生成字符串
s
,方法是将结果收集到一些
Iterable
join
中:

let s = it
    .map(|&x| x)
    .collect::<Vec<&str>>()
    .join("\n");
s=it
.map(|&x | x)
收集::()
.加入(“\n”);

但是,这不必要地为
Vec
分配内存。有更直接的方法吗?

在rust文档中有相关的示例:

let words=[“alpha”,“beta”,“gamma”];
//chars()返回一个迭代器
让合并:String=words.iter()
.flat_映射(|s | s.chars())
.收集();
断言!(合并为“Alphabetagama”);
您还可以使用
Extend
trait:

fn f>(数据:I)->字符串{
让mut ret=String::new();
ret.extend(数据);
ret
}
您可以通过使用迭代器的函数轻松完成:

let s = it.fold(String::new(), |a, b| a + b + "\n");
完整代码如下所示:

fn main() {
    let xs = vec!["first", "second", "third"];
    let it = xs.into_iter();

    // let s = it.collect::<Vec<&str>>().join("\n");

    let s = it.fold(String::new(), |a, b| a + b + "\n");
    let s = s.trim_end();

    println!("{:?}", s);
}
fn main(){
设xs=vec![“第一”、“第二”、“第三”];
让它=xs.into_iter();
//让s=it.collect::().join(“\n”);
让s=it.fold(String::new(),|a,b | a+b+“\n”);
设s=s.trim_end();
println!(“{:?}”,s);
}

编辑:在塞巴斯蒂安·雷德尔(Sebastian Redl)的评论之后,我检查了折叠使用的性能成本,并在操场上创建了一个

您可以看到,对于许多迭代方法,
fold
的使用要花费更多的时间

但未检查分配的内存使用情况。

您可以使用itertools板条箱进行检查。我在示例中使用了helper,它几乎是迭代器的连接等价物

&str
项转换为
&str
项时需要
cloned()
,它不执行任何分配。当
rust@1.36
获得稳定的发行版

使用itertools::itertools;//0.8.0
fn main(){
让单词=[“alpha”,“beta”,“gamma”];
让合并:String=words.iter().cloned().Interspose(“,”).collect();
assert_eq!(合并为“alpha、beta、gamma”);
}

抱歉-我最初的回答删除了迭代器,但你的问题是如何加入迭代器而不是分配额外的向量。@SimonWhitehead无需担心;我想知道我是否应该说得更清楚。看起来像是
itertools
板条箱注意到,根据迭代器的确切特征,收集到一个切片向量,然后进行连接实际上可能比使用Websterix的方法或
itertools
更快,因为
SliceConcatExt::join
可以提前计算整个字符串所需的大小,因此在累积期间绝对不需要重新分配;而其他方法可能必须重新分配字符串。您应该明确地进行基准测试。@chpio它必须进行分配,但如果迭代器给出了一个良好的大小提示,则不能重新分配。这个答案不会再现OP的需要。OP询问是否穿插了一些常量字符串(例如“\n”)?。由于字符串已经实现了
Extend
,因此在没有
flat\u map
的情况下,这也应该可以工作。之所以速度慢,是因为您在每次迭代中使用+创建两个新字符串。如果使用单个字符串(),它的工作效果会比collect和join()更好。添加了
black_box
,并分别为每个测试创建vec(因为缓存变暖)()。由于延迟/持续时间的巨大差异,Playerd不太适合基准测试,但折叠变体似乎稍微慢一点(多次运行)。使用
black_-box(xs).iter().copied()
现在需要两倍于collect+join-over-fold的时间(黑色_-box(xs)没有关系,
xs
是一样的)。我猜他们优化了一些东西,比如
vec![“嘿”;100_000]。放入iter()。收集
只返回原始vec?!对