为何Rust中trim_matches无法像trim_right_matches一样使用&str?
为什么Rust中
trim_matches不能传字符串,但trim_right_matches可以? 这问题我之前踩过坑,其实核心是两个方法对传入的Pattern(匹配模式)要求不一样~
先看你的问题重现
首先是正常运行的代码:
println!("{}", "[(foo)]".trim_right_matches(")]")); // 输出[(foo
而这段代码会触发编译错误:
println!("{}", "[(foo)]".trim_matches("[()]"));
错误信息如下:
error[E0277]: the trait bound
std::str::pattern::StrSearcher<'_, '_>: std::str::pattern::DoubleEndedSearcher<'_>is not satisfied
--> test.rs:2:27
| 2 | println!("{}", "[(foo)]".trim_matches("[()]");
| ^^^^^^^^^^^^ the traitstd::str::pattern::DoubleEndedSearcher<'_>is not implemented forstd::str::pattern::StrSearcher<'_, '_>
原因解析
trim_matches的作用是从字符串的两端同时移除匹配的内容,这就要求它的匹配模式必须能同时从左到右、从右到左进行查找——也就是对应的Searcher必须实现DoubleEndedSearchertrait。- 当你传入字符串作为匹配模式时,Rust会使用
StrSearcher来处理,但这个类型并没有实现DoubleEndedSearcher。原因很简单:字符串匹配是有顺序的,比如你传"[]",左边找的是"[",右边找的是"]",但Rust没法确定你到底是要匹配整个字符串,还是单个字符,所以干脆不支持这种用法。 - 而
trim_right_matches只需要从右侧单向查找,只需要普通的Searcher即可,所以字符串作为模式是完全没问题的。
解决办法
如果你想实现“移除两端的[、(、)、]这些字符”的需求,别用字符串,改用以下两种方式:
1. 使用字符集合
直接指定要匹配的单个字符数组:
println!("{}", "[(foo)]".trim_matches(&['[', '(', ')', ']'][..])); // 输出: foo
2. 使用闭包判断
通过闭包来匹配符合条件的字符:
println!("{}", "[(foo)]".trim_matches(|c| matches!(c, '[' | '(' | ')' | ']'))); // 输出: foo
内容的提问来源于stack exchange,提问作者blz
相关产品推荐
相关产品推荐

