我正在编写一个函数,它需要一个更大整数的个别数字来执行操作.
我尝试过以下方法:
// I can safely unwrap because I know the chars of the string are going to be valid
let digits = num.to_string().chars().map(|d| d.to_digit(10).unwrap());
Run Code Online (Sandbox Code Playgroud)
但借阅检查员表示字符串的寿命不够长.
以下工作:
let temp = num.to_string();
let digits = temp.chars().map(|d| d.to_digit(10).unwrap());
Run Code Online (Sandbox Code Playgroud)
但这看起来更加做作.
这样做有更好的,可能更自然的方式吗?
但借阅检查员表示字符串的寿命不够长.
那是因为它没有.你没有使用迭代器,所以类型digits是
std::iter::Map<std::str::Chars<'_>, <closure>>
Run Code Online (Sandbox Code Playgroud)
也就是说,还没有到被评估的迭代器,包含对分配的字符串(未命名的寿命引用'_的Chars).但是,由于该字符串没有所有者,因此在语句结束时删除它.在迭代器被消耗之前.
所以,对于Rust来说,它阻止了一个免费使用后的bug!
使用迭代器会"解决"问题,因为对分配的字符串的引用不会尝试比分配的字符串活得更久; 他们都在声明的最后结束:
let digits: Vec<_> = num.to_string().chars().map(|d| d.to_digit(10).unwrap()).collect();
Run Code Online (Sandbox Code Playgroud)
fn x(n: usize) -> Vec<usize> {
fn x_inner(n: usize, xs: &mut Vec<usize>) {
if n >= 10 {
x_inner(n / 10, xs);
}
xs.push(n % 10);
}
let mut xs = Vec::new();
x_inner(n, &mut xs);
xs
}
fn main() {
let num = 42;
let digits: Vec<_> = num.to_string().chars().map(|d| d.to_digit(10).unwrap()).collect();
println!("{:?}", digits);
let digits = x(42);
println!("{:?}", digits);
}
Run Code Online (Sandbox Code Playgroud)
但是,您可能希望为负数添加所有特殊情况逻辑,并且测试不是一个坏主意.
您可能还需要一个花式裤子迭代器版本:
struct Digits {
n: usize,
divisor: usize,
}
impl Digits {
fn new(n: usize) -> Self {
let mut divisor = 1;
while n >= divisor * 10 {
divisor *= 10;
}
Digits {
n: n,
divisor: divisor,
}
}
}
impl Iterator for Digits {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
if self.divisor == 0 {
None
} else {
let v = Some(self.n / self.divisor);
self.n %= self.divisor;
self.divisor /= 10;
v
}
}
}
fn main() {
let digits: Vec<_> = Digits::new(42).collect();
println!("{:?}", digits);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2982 次 |
| 最近记录: |