返回映射中的字符串变量而不进行克隆



我正在Rust:中写一个简单的fizzbuzz

fn main() {
let fizz = "Fizz".to_string() ;
let buzz = "Buzz".to_string() ;
let fizzbuzz = "FizzBuzz".to_string() ;
let even_numbers = (1..16)
.into_iter()
.map( |n|
if n % 15 == 0 { fizzbuzz.to_owned() }
else if n % 3 == 0 { fizz.to_owned() }
else if n % 5 == 0 { buzz.to_owned() }
else { n.to_string() }
).collect::<Vec<String>>() ;
dbg!(even_numbers) ;
}

我坚持使用map(),而不是循环和逐行打印。

但这似乎不对,因为.to_owned()制作了String的克隆副本。所以我想改为这样做:

if n % 15 == 0 { fizzbuzz }
else if n % 3 == 0 { fizz }
else if n % 5 == 0 { buzz }
else { n.to_string() }

因此,这将返回所有变量。只要even_numbers矢量在内存中,也要将fizz、buzz和fizzbuzz变量保存到内存中。

我怎样才能在铁锈中做到这一点?

重复应用程序:

use std::borrow::Cow;
fn main() {
let fizz = "Fizz";
let buzz = "Buzz";
let fizzbuzz = "FizzBuzz";
let even_numbers = (1..16)
.into_iter()
.map(|n| {
if n % 15 == 0 {
fizzbuzz.into()
} else if n % 3 == 0 {
fizz.into()
} else if n % 5 == 0 {
buzz.into()
} else {
n.to_string().into()
}
})
.collect::<Vec<Cow<_>>>();
dbg!(even_numbers);
}

Vec的类型取决于您需要进一步处理此集合。如果只读访问足够,您可以使用std::rc::Rc引用计数指针。然后不克隆字符串数据,而是递增引用计数器。

正如Stargateur在下面的评论中提到的那样,你可以保留str而不是String,这更有效。

use std::rc::Rc;
fn main() {
let fizz: Rc<str> = Rc::from("Fizz");
let buzz: Rc<str> = Rc::from("Buzz");
let fizzbuzz: Rc<str> = Rc::from("FizzBuzz");
let even_numbers = (1..16)
.into_iter()
.map(|n| {
if n % 15 == 0 {
fizzbuzz.clone()
} else if n % 3 == 0 {
fizz.clone()
} else if n % 5 == 0 {
buzz.clone()
} else {
n.to_string().into()
}
})
.collect::<Vec<Rc<str>>>();
dbg!(even_numbers);
}

游乐场链接

最新更新