Chaining functions yields error method not found in `()`*

I want to sort, dedup and sum a vector. I am trying to understand why this works:

    let ans: u32 = v.iter().sum();

but when I try to chain further, I get an error method not found in ():

    let ans: u32 = v.iter().sum();

Ideally I would like to chain all of those commands together. Would someone please explain what the problem is?

Here is the code in the playground:

sort works in place on slices, it doesn't consume and return a Vec or &mut Vec for example. (You probably want sort_unstable).

dedup is a method that takes &mut Vec and also doesn't return anything.

itertools might offer some alternatives, with various tradeoffs.

The API is just designed to mutate in place, instead of returning the value.

Rust has single ownership. You can't have the same value be in two places (the variable you had, and the returned value). This means sort/dedup can't also return the value for convenience of chaining, because then they would have to only return it, and couldn't let you use the non-chaining syntax, because your original variable would have been moved to the return value.

The tap crate provides the Tap::tap_mut adapter, which you could use to rewrite your call like this:

let v = v
   .tap_mut(|v| v.sort())
   .tap_mut(|v| v.dedup());

However, I would go for the current route, this involves too much boilerplate for me and reduces code readability imo.

Method "chaining" is not just some arbitrary syntax made up for putting stuff on one line. Methods are regular functions with all the same typing rules as any other function. If a method doesn't declare returning anything (ie., it has unit return type), then you can't just expect that it will somehow magically return the receiver.

It's possible to write methods that simply return the receiver, but the methods you are calling don't. This could have been inferred from their signature, which you should be able to find yourself in the official documentation.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.