Syntax question - calling method in map

Hi, I have a simple question about method calling.
This code works

struct S {}
impl S {
    fn f(&self, x: &i32) -> i32 {
        x * x
    }
}
fn main() {
    let s = S {};
    let v = vec![1, 2, 3];

    let w = v.iter().map(|x| s.f(x)).collect::<Vec<_>>();
    println!("{:?}", w);
}

but calling s.f method directly

let w = v.iter().map(s.f).collect::<Vec<_>>();

raises error[E0615]: attempted to take value of method fon typeS`.

Is there a way around it or is it just how Rust syntax works?

It's just how Rust syntax works. map is expecting something that takes one argument, S::f takes two arguments, and there's no automatic currying (e.g. s.f isn't a currying operation). Your closure is effectively doing the currying.

If the closure in question is complicated, it doesn't have to be specified inline.

    let sf = |x| s.f(x);
    let w = v.iter().map(sf).collect::<Vec<_>>();
1 Like

Thank you! I'll stick then to using the closure.

Took me a minute, but I remembered why s.f being an automatic curry expression isn't going to happen: you can have a field and a method with the same name.

2 Likes

Just to note, Java has a syntax that allows s::f (i.e. local variable name, separator, method name, as in myList::add) to be used as an automatic curry expression, but that would break backwards compatibility if added to Rust as it is currently allowed to give structs lowercase names. Even though it's somewhat inconsistent with usual usage of the path separator and could not implemented without an edition barrier it still looks very stylish imo.

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.