6

I need to split a String (not &str) by another String:

use std::str::Split;

fn main() {
    let x = "".to_string().split("".to_string());
}

Why do I get this error and how to avoid it if I already have to operate on strings?

error[E0277]: the trait bound `std::string::String: std::ops::FnMut<(char,)>` is not satisfied
 --> src/main.rs:4:32
  |
4 |         let x = "".to_string().split("".to_string());
  |                                ^^^^^ the trait `std::ops::FnMut<(char,)>` is not implemented for `std::string::String`
  |
  = note: required because of the requirements on the impl of `std::str::pattern::Pattern<'_>` for `std::string::String`

According to the #rust-beginners IRC channel, this might be an example of Deref failing in 1.20.0-nightly. How to split a string in Rust? doesn't address the problem of splitting by String, not &str.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
d33tah
  • 10,999
  • 13
  • 68
  • 158
  • Possible duplicate of [How to split a string in Rust?](https://stackoverflow.com/questions/26643688/how-to-split-a-string-in-rust) – Stargateur Jul 07 '17 at 15:17
  • What is the problem ? https://play.rust-lang.org/?gist=ee9fee6ce0c6a68472f918732fb14e8e&version=stable&backtrace=0 – Stargateur Jul 07 '17 at 15:18
  • No... https://play.rust-lang.org/?gist=e1d53c52c2615979c59c1910c0cadd29&version=nightly&backtrace=0 – Stargateur Jul 07 '17 at 15:22
  • Yup, passing a reference to String instead of the String itself does solve the error message - you could post that as a separate answer. In order to reproduce the error, remove `&` from your code. – d33tah Jul 07 '17 at 15:23
  • I don't think this is an exact duplicate, but in other side, a glance at the documentation would have solve the issue. – Boiethios Jul 07 '17 at 15:25
  • 1
    @Boiethios: only if you know that in this particular case String won't get derefed. – d33tah Jul 07 '17 at 15:26

2 Answers2

6

All is in the documentation. You can provide one of:

  • A &str,
  • A char,
  • A closure,

Those three types implement the Pattern trait. You are giving a String to split instead of a &str.

Example:

fn main() {
    let x = "".to_string();
    let split = x.split("");
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Boiethios
  • 38,438
  • 19
  • 134
  • 183
4

I talked about this with #rust-beginners IRC channel and heard the following:

15:12:15           achird | d33tah: split accepts a Pattern, where Pattern can be &str or char, but you're passing a String (no idea why deref is not working)
15:13:01           d33tah | achird: thanks! how can I convert string to str?
15:13:03           achird | i think a simple split(&delimiter2) should fix the problem
15:16:26           calops | why isn't deref working though?
15:21:33        @mbrubeck | calops, d33tah: Deref coercions only work if one exact "expected" type is known.  For a generic type like <P: Pattern>, coercion doesn't kick in.
15:24:11        @mbrubeck | d33tah: The error should definitely be improved...  It should complain that `String` doesn't impl `Pattern`, instead of jumping straight to `FnMut(char)`

So basically, the solution is to add & before the delimiter string, like this:

fn main() {
    let s1 = "".to_string();
    let s2 = "".to_string();
    let x = s1.split(&s2);
}
Boiethios
  • 38,438
  • 19
  • 134
  • 183
d33tah
  • 10,999
  • 13
  • 68
  • 158