如何在循环中重复执行字符串替换?
How to repeatedly perform string replacement in a loop?
我正在编写一种方法来循环遍历地图的 (from, to)
并执行多轮 tmp = tmp.replace(from, to)
。我仍在努力掌握 Rust
的所有权概念
#[macro_use]
extern crate lazy_static;
use std::collections::HashMap;
lazy_static! {
static ref REPLACEMENTS: HashMap<&'static str, &'static str> = {
let mut m = HashMap::new();
m.insert("abc", "def");
m.insert("com", "org");
m
};
}
fn replace_path_name(path: &str) -> &str {
let mut tmp = path;
for (from, to) in REPLACEMENTS.iter() {
let a = *from;
let b = *to;
tmp = tmp.replace(a, b);
}
tmp
}
fn main() {}
这段代码让我...
error[E0308]: mismatched types
--> src/main.rs:22:15
|
22 | tmp = tmp.replace(a, b);
| ^^^^^^^^^^^^^^^^^
| |
| expected &str, found struct `std::string::String`
| help: consider borrowing here: `&tmp.replace(a, b)`
|
= note: expected type `&str`
found type `std::string::String`
额外的 a
和 b
是我试图弄清楚为什么 Rust 使 from
和 to
变成 &&str
.
第一个问题是您的 return 值:&str
。您正在 return 引用某物,但是什么 拥有 该值?您不能 return 对局部变量的引用。
第二个问题是str::replace
的return类型,是String
,不是&str
。这就是错误消息的原因:您正试图将 String
存储在只能存储 &str
的变量中。你不能那样做。
最简单 修复不是最有效的;无条件创建一个String
:
fn replace_path_name(path: &str) -> String {
let mut tmp = String::from(path);
for (from, to) in REPLACEMENTS.iter() {
tmp = tmp.replace(from, to);
}
tmp
}
在某些情况下,您也可以使用 Cow
这样的类型来节省一点分配:
use std::borrow::Cow;
fn replace_path_name(path: &str) -> String {
let mut tmp = Cow::from(path);
for (from, to) in &*REPLACEMENTS {
tmp = tmp.replace(from, to).into();
}
tmp.into()
}
甚至可以 returned 以便在不存在替换时不进行分配:
use std::borrow::Cow;
fn replace_path_name(path: &str) -> Cow<str> {
let mut tmp = Cow::from(path);
for (from, to) in &*REPLACEMENTS {
tmp = tmp.replace(from, to).into();
}
tmp
}
或使用 Iterator::fold
的等效功能:
use std::borrow::Cow;
fn replace_path_name(path: &str) -> Cow<str> {
REPLACEMENTS
.iter()
.fold(Cow::from(path), |s, (from, to)| s.replace(from, to).into())
}
不幸的是 str::replace
没有 return Cow<str>
。如果是这样,如果不进行替换,则不会进行分配。
另请参阅:
- Is there any way to return a reference to a variable created in a function?
- Running a number of consecutive replacements on the same string
我正在编写一种方法来循环遍历地图的 (from, to)
并执行多轮 tmp = tmp.replace(from, to)
。我仍在努力掌握 Rust
#[macro_use]
extern crate lazy_static;
use std::collections::HashMap;
lazy_static! {
static ref REPLACEMENTS: HashMap<&'static str, &'static str> = {
let mut m = HashMap::new();
m.insert("abc", "def");
m.insert("com", "org");
m
};
}
fn replace_path_name(path: &str) -> &str {
let mut tmp = path;
for (from, to) in REPLACEMENTS.iter() {
let a = *from;
let b = *to;
tmp = tmp.replace(a, b);
}
tmp
}
fn main() {}
这段代码让我...
error[E0308]: mismatched types
--> src/main.rs:22:15
|
22 | tmp = tmp.replace(a, b);
| ^^^^^^^^^^^^^^^^^
| |
| expected &str, found struct `std::string::String`
| help: consider borrowing here: `&tmp.replace(a, b)`
|
= note: expected type `&str`
found type `std::string::String`
额外的 a
和 b
是我试图弄清楚为什么 Rust 使 from
和 to
变成 &&str
.
第一个问题是您的 return 值:&str
。您正在 return 引用某物,但是什么 拥有 该值?您不能 return 对局部变量的引用。
第二个问题是str::replace
的return类型,是String
,不是&str
。这就是错误消息的原因:您正试图将 String
存储在只能存储 &str
的变量中。你不能那样做。
最简单 修复不是最有效的;无条件创建一个String
:
fn replace_path_name(path: &str) -> String {
let mut tmp = String::from(path);
for (from, to) in REPLACEMENTS.iter() {
tmp = tmp.replace(from, to);
}
tmp
}
在某些情况下,您也可以使用 Cow
这样的类型来节省一点分配:
use std::borrow::Cow;
fn replace_path_name(path: &str) -> String {
let mut tmp = Cow::from(path);
for (from, to) in &*REPLACEMENTS {
tmp = tmp.replace(from, to).into();
}
tmp.into()
}
甚至可以 returned 以便在不存在替换时不进行分配:
use std::borrow::Cow;
fn replace_path_name(path: &str) -> Cow<str> {
let mut tmp = Cow::from(path);
for (from, to) in &*REPLACEMENTS {
tmp = tmp.replace(from, to).into();
}
tmp
}
或使用 Iterator::fold
的等效功能:
use std::borrow::Cow;
fn replace_path_name(path: &str) -> Cow<str> {
REPLACEMENTS
.iter()
.fold(Cow::from(path), |s, (from, to)| s.replace(from, to).into())
}
不幸的是 str::replace
没有 return Cow<str>
。如果是这样,如果不进行替换,则不会进行分配。
另请参阅:
- Is there any way to return a reference to a variable created in a function?
- Running a number of consecutive replacements on the same string