如何在rust中迭代str或String的前缀和后缀?
Posted
技术标签:
【中文标题】如何在rust中迭代str或String的前缀和后缀?【英文标题】:How to iterate prefixes and suffixes of str or String in rust? 【发布时间】:2021-10-21 00:50:06 【问题描述】:我有一个字符串:“abcd”,我想:
从最短到最长迭代它的前缀:
""、"a"、"ab"、"abc"、"abcd"
从最长到最短迭代它的前缀:
“abcd”、“abc”、“ab”、“a”、“”
从最短到最长迭代其后缀:
""、"d"、"cd"、"bcd"、"abcd"
从最长到最短迭代其后缀:
“abcd”、“bcd”、“cd”、“d”、“”
【问题讨论】:
你没有说你需要这些做什么,所以不可能知道你想要字节前缀、代码点前缀还是字形前缀。您唯一的示例使用 ASCII,所有这三个东西都是等价的。 【参考方案1】:字符串比人们想象的要复杂
为了符合人类直觉,您通常希望将字符串视为由 0 个或多个字素簇组成的序列。 字素簇是 1 个或多个 Unicode 代码点的序列 在 utf8 编码中,代码点表示为 1、2、3 或 4 个字节的序列 Rust 中的 String 和 str 都使用 utf8 表示字符串,索引是 byte 偏移量 对代码点的一部分进行切片毫无意义,并且会产生垃圾数据。 Rust 选择恐慌:#[cfg(test)]
mod tests
#[test]
#[should_panic(expected = "byte index 2 is not a char boundary; it is inside '\\u306' (bytes 1..3) of `y̆`")]
fn bad_index()
let y = "y̆";
&y[2..];
要在代码点级别工作,rust 有:
str.chars() str.char_indices() str.is_char_boundary()延伸阅读:https://doc.rust-lang.org/book/ch08-02-strings.html
解决方案
警告:此代码在代码点级别工作,并且忽略了字素簇。
从最短到最长:
use core::iter;
pub fn prefixes(s: &str) -> impl Iterator<Item = &str> + DoubleEndedIterator
s.char_indices()
.map(move |(pos, _)| &s[..pos])
.chain(iter::once(s))
pub fn suffixes(s: &str) -> impl Iterator<Item = &str> + DoubleEndedIterator
s.char_indices()
.map(move |(pos, _)| &s[pos..])
.chain(iter::once(""))
.rev()
反过来:
prefixes(s).rev()
suffixes(s).rev()
test
另见:How to iterate prefixes or suffixes of vec or slice in rust?
【讨论】:
非常优雅的解决方案,比我预期的要短得多。以上是关于如何在rust中迭代str或String的前缀和后缀?的主要内容,如果未能解决你的问题,请参考以下文章
我应该如何使用&str,Option和String编组Rust函数并在C#中使用它?