正如你明确询问的
不
使用
chars()
,您必须将自己限制为ASCII字符串。
pub fn reverse2(input: &str) -> String {
// Reversing on byte-level only works with ASCII strings.
assert!(input.is_ascii());
let reversed_bytes: Vec<u8> = input.as_bytes().iter().copied().rev().collect();
let reversed_string = unsafe {
// SAFETY: This is guaranteed to be a valid UTF8 string, because:
// - the input string is a valid ASCII string
// - a reversed ASCII string is still a valid ASCII string
// - an ASCII string is a valid UTF8 string
String::from_utf8_unchecked(reversed_bytes)
};
return reversed_string;
}
如果您不喜欢
unsafe
,但它会带来一点开销:
pub fn reverse2(input: &str) -> String {
// Reversing on byte-level only works with ASCII strings.
assert!(input.is_ascii());
let reversed_bytes: Vec<u8> = input.as_bytes().iter().copied().rev().collect();
let reversed_string = String::from_utf8(reversed_bytes).unwrap();
return reversed_string;
}
优化:
检查
is_ascii()
是一些开销。然而,这并不是严格要求的。
UTF-8有一个特殊的属性:每个非ASCII字节都有值
128
及以上。因此,从技术上讲,只需简单地过滤掉所有等于或大于的值就足够了
128
:
pub fn reverse2(input: &str) -> String {
let reversed_bytes: Vec<u8> = input
.as_bytes()
.iter()
.rev()
.map(|&val| {
if val < 128 {
val
} else {
0x1a // replacement char
}
})
.collect();
let reversed_string = unsafe {
// SAFETY: This is guaranteed to be a valid UTF8 string, because:
// - `reversed_bytes` is guaranteed to be an ASCII string
// - an ASCII string is a valid UTF8 string
String::from_utf8_unchecked(reversed_bytes)
};
return reversed_string;
}
fn main() {
let s = "abcdeðfghij";
println!("{:?}", s.as_bytes());
let reversed = reverse2(s);
println!("{}", reversed);
println!("{:?}", reversed.as_bytes());
}
[97, 98, 99, 100, 101, 240, 159, 152, 131, 102, 103, 104, 105, 106]
jihgfedcba
[106, 105, 104, 103, 102, 26, 26, 26, 26, 101, 100, 99, 98, 97]
附加备注:
考虑使用
.bytes()
而不是
.as_bytes().iter()
。