Rust 使绳子生锈
我试图在Rust中做一个简单的字符串反转,但我似乎不知道要使用什么函数来实现这一点 假设我有一个字符串:Rust 使绳子生锈,rust,Rust,我试图在Rust中做一个简单的字符串反转,但我似乎不知道要使用什么函数来实现这一点 假设我有一个字符串:\uuuuuuuuuux\uuuux 将此字符串反转为:xxxx\ux\uuuxx\ux 我试过: //res is the string I want to invert for mut c in res.as_slice().chars() { c = match c { 'x' => '_', _ => 'x' }; }; 但
\uuuuuuuuuux\uuuux
将此字符串反转为:xxxx\ux\uuuxx\ux
我试过:
//res is the string I want to invert
for mut c in res.as_slice().chars() {
c =
match c {
'x' => '_',
_ => 'x'
};
};
但是这警告我,值c
永远不会被读取,所以我猜我使用的c
实际上不是对片中字符的引用?.chars()
产生的char
实例在任何方面都不是引用
为了能够在适当的位置修改这样的东西,您需要有一个可变的切片
字符串
是UTF-8编码的;如果您希望就地执行,则任何字符替换都必须针对具有相同字节数的字符;最简单的例子是ASCII。(以x
和
为例,它必须是ASCII。)
落实这一点的方法是:
(我插入了分支以保证UTF-8不变量。尽管将其作为debug\u assert!
放置可能还是一个好主意,如果您知道您只处理ASCII。)
或者,您可以从中创建一个新字符串。这将处理非ASCII字符串
res.chars().map(|c| if c == 'x' { '_' } else { 'x' }).collect::<String>()
res.chars()
使用代码点作为边界也不是很精确,因此让我们在本例中使用
res.graphemes(true).map(|c| if c == "x" { '_' } else { 'x' }).collect::<String>()
res.graphemes(true).map(| c | if c==“x”{'}else{'x'})。collect:()
以下是我的看法:
输出:
___xxx__x_
xxx___xx_x
xxx___xx_x
令人烦恼的是,由于“shift_char”是O(n),所以就地版本是O(n^2)。但是我不知道如何直接更改单个字符。安全有效地映射保证ASCII输入的方法是通过+
.mut_iter()
+。(这部分图书馆确实需要一些工作…)我需要包括什么吗?rust说,as_mut_slice()
不是String
的一部分,而且我在String文档中没有看到任何类似的内容。这应该附带一个警告,即字符串必须完全是ASCII(也就是说,仅将字符反转为ASCII是不够的)。我的rust告诉我,转换为_String()
不存在于Vec
@SyntacticFructose,我怀疑您必须更新您的rust,因为它变化非常频繁。我不知道play.rust-lang.org上有哪个版本,但它在那里工作。如果UTF-8字符串包含127以外的任何代码点,第一个函数将在你面前爆炸。char_at的索引是一个字节偏移量,如果在多字节编码的代码点中间使用offest,则会导致任务失败。@sellibitze——因为这两个字符是事先知道的,所以这是正确的。另外,您知道如何在恒定时间内替换字符串中的字符,而不使用其他变量吗?例如,在大多数语言中,字符串只是字符数组,所以您可以只执行str[i]=“x”或其他操作。我在这里找不到这样做的方法。
fn main() {
let mut res = String::from_str("____x_xx__x").into_ascii();
for c in res.mut_iter() {
*c = match c.to_char() {
'x' => '_',
_ => 'x'
}.to_ascii();
};
println!("{}", res.into_string());
}
fn new_str(s: &String) -> String {
let mut s2 = String::new();
for i in range(0,s.len()) {
s2 = s2.append(if s.as_slice().char_at(i) == '_' { "x" } else { "_" });
}
s2
}
fn in_place(s: &mut String) {
for _i in range(0,s.len()) {
let c = s.shift_char();
match c {
Some(x) => s.grow(1,if x == '_' { 'x' } else { '_' }),
None => return
}
}
}
fn main() {
let s = String::from_str("___xxx__x_");
let s2 = new_str(&s);
println!("{}",s);
println!("{}",s2);
let mut s3 = String::from_str("___xxx__x_");
in_place(&mut s3);
println!("{}",s3);
}
___xxx__x_
xxx___xx_x
xxx___xx_x