如何在Rust中创建str

pxyaymoc  于 2022-12-04  发布在  其他
关注(0)|答案(2)|浏览(185)

假设变量c中有一个char,变量n中有一个正的int,我想构建包含cstrc出现n次,我该怎么做呢?
我试着把它构建成一个String,也许我只是在读字符串的文档时感到头晕,但是我不知道如何把它转换成一个str。但是如果我试着直接把它构建成一个str,我也不知道如何做。
对于context,下面是我尝试实现的完整函数:它获取一个字符串,并找到最长的连续字符序列(通过获取第一个出现的字符来打破平局)。

pub fn longest_sequence(s: &str) -> Option<&str> {
    if s.len() == 0 { return None; }
    let mut current_c = s.as_bytes()[0] as char;
    let mut greatest_c = s.as_bytes()[0] as char;
    let mut current_num = 0;
    let mut greatest_num = 0;
    for ch in s.chars() {
        if current_c == ch {
            current_num += 1;
            if current_num > greatest_num {
                greatest_num = current_num;
                greatest_c = current_c;
            }
        } else {
            current_num = 1;
            current_c = ch;
        }
    }
    // Now build the output str ...
}
z4bn682m

z4bn682m1#

我认为关于strString有一些误解。

  • str永远不会单独存在。它总是被用作&str(或者Box<str>*str,但在您的情况下,这些都不重要)。
  • &str不拥有任何数据。它只是对另一个String(的一部分)的引用。
  • String实际上保存数据。
  • 所以当你想返回数据时,使用String;如果要引用现有数据,请返回&str
      • 无法**将本地String转换为&str。数据必须存储在某个地方,而&str不存储它。(为了完整起见:是的,您可以泄漏它,但这将在内存中创建一个永久字符串,永远不会再消失)

所以在你的情况下有两种方法:

  • 引用输入&str,因为它的数据已经存储在某处。
  • 请改为返回String

作为旁注:不要执行s.as_bytes()[0] as char,因为它不适用于UTF8字符串。Rust字符串被定义为UTF8。
以下是一个可能的解决方案:
第一个
一些解释:

  • 不需要检查空字符串。s.chars().next()?会自动执行此操作。
  • 使用s.chars().next()而不是s.as_bytes()[0] as char,因为第二个不兼容UTF8。
  • 我显式存储greatest_len而不是使用greatest.len(),因为greatest.len()也不兼容UTF8,因为它以字节为单位提供字符串的大小,而不是以字符为单位。
  • 只要找到具有相同值的新字符,就存储新的最大字符串;我不得不把它移到char类型改变的情况下(在循环后一次),因为我们还不知道当前char的结尾。再次注意,&s[current_start..current_start+current_len]将不起作用,因为&s[ .. ]希望索引在bytes中,但current_lenchars中。所以我们需要等待另一个char来知道前一个char的结尾。

根据您的代码,另一个解决方案是:
第一次

7kqas0il

7kqas0il2#

要将String转换为&'static str,需要如下泄漏:

fn leak(s: String) -> &'static str {
    let ptr = s.as_str() as *const str;
    core::mem::forget(s);
    unsafe {&*ptr}
}

以及charString

fn cts(c: char, n: usize) -> String {
    (0..n)
        .map(|_| c)
        .collect()
}

所以char&'static str基本上看起来像这样:

fn conv(c: char, n: usize) -> &'static str {
    leak(cts(c, n))
}

我不建议泄漏的String tho,只是使用它是。

相关问题