我如何在 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();
但是你的代码还有其他问题:
- 你正在使用第一个字符来检查字符串是否为空,然后你从迭代的其余部分构建一个字符串,然后让第一个字符替换该字符串的第一个字符...丢失这个字符是初始 str
的第二个字符
- 您正在构建无用的 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。
我正在做 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();
但是你的代码还有其他问题:
- 你正在使用第一个字符来检查字符串是否为空,然后你从迭代的其余部分构建一个字符串,然后让第一个字符替换该字符串的第一个字符...丢失这个字符是初始 str 的第二个字符
- 您正在构建无用的 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。