我正在尝试实现以下代码,它从 Cow<str>
的切片中删除前缀的。
fn remove_prefix(v: &mut [Cow<str>], prefix: &str) {
for t in v.iter_mut() {
match *t {
Borrowed(&s) => s = s.trim_left_matches(prefix),
Owned(s) => s = s.trim_left_matches(prefix).to_string(),
}
}
}
我有两个问题:
我无法编译它 - 我已经尝试了很多
&
的组合的和*
的,但无济于事。有没有更好的方法将函数应用于
Cow<str>
无需match
它到Borrowed
和Owned
每次。我的意思是似乎我应该能够做类似*t = t.trim_left_matches(prefix)
的事情如果t
是Borrowed(str)
它将其保留为str
(因为trim_left_matches
允许这样做),如果它是一个Owned(String)
它将其保留为String
.同样对于replace()
它会意识到它必须将两者都转换为String
(因为你不能在replace()
上使用str
)。这样的事情可能吗?
最佳答案
问题 #1 强烈暗示您认为模式匹配和/或指针在 Rust 中的工作方式与它们的实际工作方式并不完全一致。编译以下代码:
fn remove_prefix(v: &mut [Cow<str>], prefix: &str) {
use std::borrow::Cow::*;
for t in v.iter_mut() {
match *t {
Borrowed(ref mut s) => *s = s.trim_left_matches(prefix),
Owned(ref mut s) => *s = s.trim_left_matches(prefix).to_string(),
}
}
}
如果你的情况,Borrowed(&s)
与 Borrowed(&str)
匹配,这意味着 s
是 str 类型
。这是不可能的:您绝对不能拥有动态大小类型的变量。这也会适得其反。鉴于您想要修改 ,按值绑定(bind)到它根本无济于事。
您想要 的是修改包含在Borrowed
变体中的东西。这意味着您需要一个指向该存储位置的可变指针。因此,Borrowed(ref mut s)
:这根本不是解构 Borrowed
中的值。相反,它直接绑定(bind)到 &str
,这意味着 s
是 &mut &str
类型;指向 a 的可变指针(指向 str
的指针)。换句话说:指向字符串切片的可变指针。
此时,通过可变指针重新分配值来改变Borrowed
的内容:*s = ...
。
最后,完全相同的推理适用于 Owned
情况:您试图按值绑定(bind),然后对其进行变异,这不可能达到您想要的效果。相反,通过可变指针绑定(bind)到存储位置,然后重新分配它。
至于问题 #2... 不是。这将意味着某种重载,而 Rust 不会这样做(通过故意选择)。如果您经常这样做,您可以编写一个扩展特征,将感兴趣的方法添加到 Cow
。
关于string - Cow<str> 切片的通用操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31806770/