【发布时间】:2020-10-14 20:28:28
【问题描述】:
如何检查一个字符串是否包含 Rust 中的任何空格?
例如,这些都应该返回 true:
"Hello, world!""Hello\n""This\tis\ta\ttab"
【问题讨论】:
如何检查一个字符串是否包含 Rust 中的任何空格?
例如,这些都应该返回 true:
"Hello, world!""Hello\n""This\tis\ta\ttab"【问题讨论】:
您可以将char::is_whitespace 传递给.contains():
assert!("Hello, world!".contains(char::is_whitespace));
assert!("Hello\n".contains(char::is_whitespace));
assert!("This\tis\ta\ttab".contains(char::is_whitespace));
如果字符具有 Unicode White_Space 属性,则char::is_whitespace 返回 true。
或者,如果您只想匹配 ASCII 空格(空格、水平制表符、换行符、换页或回车),您可以使用 char::is_ascii_whitespace:
// This has a non-breaking space, which is not ASCII.
let string = "Hello,\u{A0}Rust!\n";
// Thus, it's *not* ASCII whitespace
assert!(!string.contains(char::is_ascii_whitespace));
// but it *is* Unicode whitespace.
assert!(string.contains(char::is_whitespace));
【讨论】:
string.as_bytes().iter().any(u8::is_ascii_whitespace)
char的闭包调用.contains(...)意味着遍历所有Unicode代码点,包括多字节代码点,将每个多字节序列转换为char并调用is_ascii_whitespace在上面。其中很多都可以优化掉,而且确实如此,但是当您只要求编译器查找属于有限集合之一的所有字节时,它会使编译器的事情变得更容易。 You can compare the generated assembly code; u8::is_ascii_whitespace 大约是 char::is_ascii_whitespace 大小的四分之一(这是带有完整优化)。
0..=127 范围内的字节永远不会出现在其中。这样代码可以写得更简单。理论上编译器可以知道这一点并根据该假设进行优化,但实际上它不会。
正如有人提到的,如果你不需要处理 Unicode,它会更快 只需明确命名您关心的角色:
fn main() {
let a = vec!["false", "true space", "true newline\n", "true\ttab"];
let a2: &[char] = &[' ', '\n', '\t'];
for s in a.iter() {
let b = s.contains(a2);
println!("{}", b);
}
}
【讨论】:
.contains() 可能会更快:string.as_bytes().iter().any(u8::is_ascii_whitespace)