我可以在函数链接时遇到 None 时立即 return 吗?
Can I return immediately when meets None while function chaining?
Problem.
我对此很好奇,因为如果可以的话,我认为我不需要这段代码中的东西。
我特别想要 .filter_map(|ch| ch.to_digit(10))
.
ch.to_digit()
returns None 如果 ch 不是数字。那么我想要 return false.
如果我能做到这一点,我想我不需要 if !code.chars().all(|ch| ch.is_digit(10) || ch.is_whitespace())
这张支票。
(我只是想知道如果在链接中进行检查,我可以这样做吗?)
如果不允许,有没有办法在函数链中进行异常检查?
谢谢。
/// Check a Luhn checksum.
pub fn is_valid(code: &str) -> bool {
if code.trim().len() <= 1 {
return false;
}
if !code.chars().all(|ch| ch.is_digit(10) || ch.is_whitespace()) {
return false;
}
code.chars()
.rev()
.filter_map(|ch| ch.to_digit(10))
.enumerate()
.map(|( i, n)|
match i % 2 {
0 => n,
_ if n == 9 => n,
_ => (n * 2) % 9,
}
)
.sum::<u32>() % 10 == 0
}
Can I return immediately when meets None while function chaining?
不是真的。您可以 map
到 Option
(而不是 filter_map
),然后 collect
Iterator<Option<_>>
到 Option<Vec<_>>
:
let items = vec![0_u16, 1, 2];
let res: Option<Vec<u16>> = items
.iter()
.map(|x| x.checked_add(1))
.collect();
assert_eq!(res, Some(vec![1, 2, 3]));
let res: Option<Vec<u16>> = items
.iter()
.map(|x| x.checked_sub(1))
.collect();
assert_eq!(res, None);
如果最后有一个None
,那么你就可以保释了。
但老实说,我只是使用沼泽标准 for
循环,例如:
let mut sum = 0;
for (i, n) = code.chars().rev().map(|ch| ch.to_digit(10)).enumerate() {
sum += match (i % 2, n) {
(_, None) => return false;
(0, Some(n)) => n,
(_, Some(9)) => 9,
(_, Some(n)) => (n * 2) % 9,
}
}
sum % 10 == 0
If it's not allowed, is there some way to do exception check in function chain?
不太清楚你的意思。
你可以 try_fold
:
pub fn is_valid(code: &str) -> bool {
code.chars()
.rev()
.try_fold((0, 0), |acc, ch|
// `acc.0` enumerates the valid digits
// `acc.1` accumulates the sum
if ch.is_whitespace() {
Some (acc)
} else {
ch.to_digit (10).map (|n|
match acc.0 % 2 {
0 => (acc.0+1, acc.1 + n),
_ if n == 9 => (acc.0+1, acc.1 + n),
_ => (acc.0+1, acc.1 + (n*2)%9),
})
})
.map (|acc| acc.1 % 10 == 0)
.unwrap_or (false)
}
但是为了可读性,我会使用@Masklinn 的直截了当的 for
循环。
Problem.
我对此很好奇,因为如果可以的话,我认为我不需要这段代码中的东西。
我特别想要 .filter_map(|ch| ch.to_digit(10))
.
ch.to_digit()
returns None 如果 ch 不是数字。那么我想要 return false.
如果我能做到这一点,我想我不需要 if !code.chars().all(|ch| ch.is_digit(10) || ch.is_whitespace())
这张支票。
(我只是想知道如果在链接中进行检查,我可以这样做吗?)
如果不允许,有没有办法在函数链中进行异常检查?
谢谢。
/// Check a Luhn checksum.
pub fn is_valid(code: &str) -> bool {
if code.trim().len() <= 1 {
return false;
}
if !code.chars().all(|ch| ch.is_digit(10) || ch.is_whitespace()) {
return false;
}
code.chars()
.rev()
.filter_map(|ch| ch.to_digit(10))
.enumerate()
.map(|( i, n)|
match i % 2 {
0 => n,
_ if n == 9 => n,
_ => (n * 2) % 9,
}
)
.sum::<u32>() % 10 == 0
}
Can I return immediately when meets None while function chaining?
不是真的。您可以 map
到 Option
(而不是 filter_map
),然后 collect
Iterator<Option<_>>
到 Option<Vec<_>>
:
let items = vec![0_u16, 1, 2];
let res: Option<Vec<u16>> = items
.iter()
.map(|x| x.checked_add(1))
.collect();
assert_eq!(res, Some(vec![1, 2, 3]));
let res: Option<Vec<u16>> = items
.iter()
.map(|x| x.checked_sub(1))
.collect();
assert_eq!(res, None);
如果最后有一个None
,那么你就可以保释了。
但老实说,我只是使用沼泽标准 for
循环,例如:
let mut sum = 0;
for (i, n) = code.chars().rev().map(|ch| ch.to_digit(10)).enumerate() {
sum += match (i % 2, n) {
(_, None) => return false;
(0, Some(n)) => n,
(_, Some(9)) => 9,
(_, Some(n)) => (n * 2) % 9,
}
}
sum % 10 == 0
If it's not allowed, is there some way to do exception check in function chain?
不太清楚你的意思。
你可以 try_fold
:
pub fn is_valid(code: &str) -> bool {
code.chars()
.rev()
.try_fold((0, 0), |acc, ch|
// `acc.0` enumerates the valid digits
// `acc.1` accumulates the sum
if ch.is_whitespace() {
Some (acc)
} else {
ch.to_digit (10).map (|n|
match acc.0 % 2 {
0 => (acc.0+1, acc.1 + n),
_ if n == 9 => (acc.0+1, acc.1 + n),
_ => (acc.0+1, acc.1 + (n*2)%9),
})
})
.map (|acc| acc.1 % 10 == 0)
.unwrap_or (false)
}
但是为了可读性,我会使用@Masklinn 的直截了当的 for
循环。