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);
}