Rust 如何将整数拆分为单个数字?

Rust 如何将整数拆分为单个数字?,rust,digits,Rust,Digits,我正在编写一个函数,它需要一个较大整数的各个数字来对其执行操作 我尝试了以下方法: fn example(num: i32) { // 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()); for digit in digit

我正在编写一个函数,它需要一个较大整数的各个数字来对其执行操作

我尝试了以下方法:

fn example(num: i32) {
    // 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());
    for digit in digits {
        println!("{}", digit)
    }
}
但是借书检查人员说,这根绳子的寿命不够长:

错误[E0716]:借用时丢弃的临时值
-->src/lib.rs:3:18
|
3 | let digits=num.to_string().chars().map(| d | d.to_digits(10.unwrap());
|^^^^^^^^^^^^^^^^-此语句末尾将释放临时值
|                  |
|创建在仍在使用时释放的临时文件
4 |数字中的数字{
|----借来以后用在这里
|
=注意:考虑使用一个“让”绑定来创建一个较长的生命值
以下方法确实有效:

let temp = num.to_string();
let digits = temp.chars().map(|d| d.to_digit(10).unwrap());
但这看起来更加做作

有没有更好、更自然的方法

但是借钱人说绳子的寿命不够长

这是因为它没有。您没有使用迭代器,所以
数字的类型是

std::iter::Map<std::str::Chars<'_>, <closure>>
如果要返回迭代器,则可以将
Vec
转换回迭代器:

fn digits(num: usize) -> impl Iterator<Item = u32> {
    num.to_string()
        .chars()
        .map(|d| d.to_digit(10).unwrap())
        .collect::<Vec<_>>()
        .into_iter()
}
fn位(num:usize)->impl迭代器{
至_字符串()的数量
.chars()
.map(| d | d.to_位(10).unwrap())
收集::()
.into_iter()
}

至于另一种解决方案,创建向量的方法有:

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);
}
fn x(n:usize)->Vec{
fn x_内部(n:usize,xs:&mut-Vec){
如果n>=10{
x_内部(n/10,xs);
}
推送(n%10);
}
让mut xs=Vec::new();
x_内部(n,&mut-xs);
xs
}
fn main(){
设num=42;
let digits:Vec=num.to_string().chars().map(|d | d.to_digit(10).unwrap()).collect();
println!(“{:?}”,数字);
设位数=x(42);
println!(“{:?}”,数字);
}
但是,您可能希望添加负数的所有特例逻辑,测试也不是一个坏主意

您可能还需要一个花式的裤子迭代器版本:

fn digits(mut num: usize) -> impl Iterator<Item = usize> {
    let mut divisor = 1;
    while num >= divisor * 10 {
        divisor *= 10;
    }

    std::iter::from_fn(move || {
        if divisor == 0 {
            None
        } else {
            let v = num / divisor;
            num %= divisor;
            divisor /= 10;
            Some(v)
        }
    })
}
fn位(mut num:usize)->impl迭代器{
设mut除数=1;
而num>=除数*10{
除数*=10;
}
标准:国际热核聚变实验堆:从| fn(移动| |{
如果除数=0{
没有一个
}否则{
设v=num/除数;
num%=除数;
除数/=10;
部分(五)
}
})
}
或完全自定义的类型:

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);
}
结构数字{
n:使用,
除数:usize,
}
impl数字{
fn新(n:usize)->Self{
设mut除数=1;
而n>=除数*10{
除数*=10;
}
数字{
n:n,
除数:除数,
}
}
}
数字的impl迭代器{
类型项=usize;
fn下一步(&mut self)->选项{
如果self.divisior==0{
没有一个
}否则{
设v=Some(self.n/自除数);
self.n%=自除数;
自除数/=10;
v
}
}
}
fn main(){
let digits:Vec=digits::new(42).collect();
println!(“{:?}”,数字);
}
另见:


我看不出在释放bug后它会如何使用。它会不会立即被使用,然后被释放?关于添加负数的特殊情况测试:使用它的函数使用
u32
,负数永远不会被使用happen@ElectricCoffee:免费后使用是因为
to_string
创建了临时的,它的寿命与创建它的语句的寿命一样长。但是,通过引用此临时语句工作的
数字
迭代器的寿命要长得多,这是不正确的。如果您在同一语句中立即调用
collect
,则不再存在问题。请告诉我@MatthieuM.!如果性能是一个问题担心它可能会进一步优化,使用/100而不是/10,并使用100种可能性的查找表,一次生成2位数字。我假设编译器可以将%和/融合到一条指令中。我为此编写了一个板条箱:
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);
}