我如何在 Rust 中加入一个字符向量

How do I join a char vector in Rust

我正在做 rustlings 练习,我试过这个来制作大写函数。但是加入部分不起作用。它说:

“结构 Vec<char> 存在方法 join,但不满足其特征界限 不满足以下特征界限: <[char] as Join<_>>::Output = _"

我不知道是什么意思。加入 char 向量的正确方法是什么?

pub fn capitalize_first(input: &str) -> String {
    let mut c = input.chars();
    match c.next() {
        None => String::new(),
        Some(first) => {
            let upper = first.to_ascii_uppercase();
            let mut v = c.collect::<Vec<char>>();
            v[0] = upper;
            v.join("")
        },
    }
}

join 方法的 return 类型有一个约束,char 类型不满足,因为它没有静态生命周期:

pub fn join<Separator>(&self, sep: Separator) -> <Self as Join<Separator>>::Output
    where
        Self: Join<Separator>,
    {
        Join::join(self, sep)
    }

您应该改用 String::from_iter

pub fn capitalize_first(input: &str) -> String {
  let mut c = input.chars();
  match c.next() {
      None => String::new(),
      Some(first) => {
          let upper = first.to_ascii_uppercase();
          let mut v = c.collect::<Vec<char>>();
          v[0] = upper;
          String::from_iter(v)
      },
  }
}

为了回答您的问题,从字符 vec 中获取字符串的最佳方法是迭代并收集:

 let my_string = my_char_vec.iter().collect();

但是你的代码还有其他问题:

  1. 你正在使用第一个字符来检查字符串是否为空,然后你从迭代的其余部分构建一个字符串,然后让第一个字符替换该字符串的第一个字符...丢失这个字符是初始 str
  2. 的第二个字符
  3. 您正在构建无用的 vec 并再次迭代。这些是您不需要的昂贵步骤

您可以通过调整代码以直接从迭代写入字符串来解决这些问题:

pub fn capitalize_first(input: &str) -> String {
    let mut chars = input.chars();
    let mut string = String::new();
    if let Some(first) = chars.next() {
        string.push(first.to_ascii_uppercase());
        for c in chars {
            string.push(c);
        }
    }
    string
}

请注意,您正在使用专用于 ASCII 字符的函数。当你确定你只处理 ASCII 时这很好,但如果你想要在国际环境中工作的东西,你想使用更通用的 to_uppercase。 由于一个unicode大写字符可能是几个字符,代码稍微复杂一点:

pub fn capitalize_first(input: &str) -> String {
    let mut chars = input.chars();
    let mut string = String::new();
    if let Some(first) = chars.next() {
        let first = first.to_uppercase();
        for c in first {
            string.push(c);
        }
        for c in chars {
            string.push(c);
        }
    }
    string
}

如果您确定可以使用to_ascii_upercase,那么还有另一种解决方案。 因为 ASCII 字符只是小写和大写的一个字节,您可以在 UTF8 字符串中更改它们:

pub fn capitalize_first(input: &str) -> String {
    let mut string = input.to_string();
    if !string.is_empty() {
        string[..1].make_ascii_uppercase();
    }
    string
}

第二种方法可用于零分配的可变字符串。但是如果第一个字符不是一个字节长,它就会 panic。