我认为对str
对String
有几个误解.
str
永远不能单独存在.它始终用作&str
(或Box<str>
或*str
,但在您的情况下,这些都不重要).
&str
不拥有任何数据.它只是对另一个String
的(部分)引用.
String
实际上保存着数据.
- 所以当你想返回data时,使用
String
;如果你想返回reference existing data,则返回&str
.
- 用is no way将本地的
String
转换为&str
.数据必须存储在某个地方,而&str
不会存储它.(为了完整起见:是的,您可以泄露它,但这将在内存中创建一个永远不会消失的字符串)
因此,在您的情况下,有两种方式:
- 引用输入
&str
,因为它的数据已经存储在某个地方.
- 相反,返回
String
分.
作为附注:不要做s.as_bytes()[0] as char
,因为它will not work与UTF8-字符串. rust 串被定义为UTF8.
这里有一个可能的解决方案:
pub fn longest_sequence(s: &str) -> Option<&str> {
let mut current_c = s.chars().next()?;
let mut current_start = 0;
let mut current_len = 0;
let mut greatest: &str = "";
let mut greatest_len = 0;
for (pos, ch) in s.char_indices() {
if current_c == ch {
current_len += 1;
} else {
if greatest_len < current_len {
greatest = &s[current_start..pos];
greatest_len = current_len;
}
current_len = 1;
current_c = ch;
current_start = pos;
}
}
if greatest_len < current_len {
greatest = &s[current_start..];
}
Some(greatest)
}
pub fn main() {
let s = "????????????????????€€????????";
let seq = longest_sequence(s);
println!("{:?}", seq);
}
Some("????????????")
以下是一些解释:
- 不需要判断空字符串.
s.chars().next()?
会自动执行此操作.
- 使用
s.chars().next()
而不是s.as_bytes()[0] as char
,因为第二个不兼容UTF8.
- 我明确地存储
greatest_len
而不是使用greatest.len()
,因为greatest.len()
也不兼容UTF8,因为它给出的字符串大小是bytes,而不是chars.
- 每当找到相同值的新字符时,就存储新的最大字符串;我必须将其移到字符类型发生变化的情况下(并且在循环之后),因为我们don't仍然知道当前字符的结尾.同样,请注意,
&s[current_start..current_start+current_len]
不起作用,因为&s[ .. ]
希望索引在bytes中,而current_len
在chars中.因此,我们需要等待另一个字符才能知道前一个字符在哪里结束.
基于您的代码的另一种解决方案是:
pub fn longest_sequence(s: &str) -> Option<String> {
let mut current_c = s.chars().next()?;
let mut greatest_c = current_c;
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;
}
}
// Build the output String
Some(std::iter::repeat(greatest_c).take(greatest_num).collect())
}
pub fn main() {
let s = "????????????????????€€????????";
let seq = longest_sequence(s);
println!("{:?}", seq);
}
Some("????????????")