Function call with a . (dot)


#1

Hello everyone,

I’m new to rust and at the moment I was reading the rust book. So my question is about first edition of the book where Error Handling is discussed.

In the book the map function is defined

fn map<F, T, A>(option: Option<T>, f: F) -> Option<A> where F: FnOnce(T) -> A {
    match option {
        None => None,
        Some(value) => Some(f(value)),
    }
}

and later it is called in the next example

fn extension(file_name: &str) -> Option<&str> {
    find(file_name, '.').map(|i| &file_name[i+1..])
}

Later in the same section a similar example is given

fn unwrap_or<T>(option: Option<T>, default: T) -> T {
    match option {
        None => default,
        Some(value) => value,
    }
}

and the call

fn main() {
    assert_eq!(extension("foobar.csv").unwrap_or("rs"), "csv");
    assert_eq!(extension("foobar").unwrap_or("rs"), "rs");
}

Since the find function in the first example returns the Option<T> type as well as the extension function, their values are then passed into the map and assert_eq!.

I know that when I implement some methods for some Struct I pass either self, &self or &mut self into the function and how the things are working is clear. However, in these two examples there is no self and consequently I would expect to call the map as

map(find(file_name, '.'), |i| &file_name[i+1..])

I could not find anything about it in the documentation.

Thanks for the help.


#2

Looking at the reference, indeed, you find
https://doc.rust-lang.org/std/option/enum.Option.html#method.map

fn map<U, F>(self, f: F) -> Option<U> where
    F: FnOnce(T) -> U, 

and
https://doc.rust-lang.org/std/option/enum.Option.html#method.unwrap_or

fn unwrap_or(self, def: T) -> T

#3

Yes indeed this is what I expect. But my question is about the book itself. There in the examples the first parameter is not self but Option<T> and this is exactly what confuses me. How can then map can be called with a dot?


#4

after this listing, the book says

Indeed, map is defined as a method on Option in the standard library. As a method, it has a slightly different signature: methods take self, &self, or &mut self as their first argument.

and then, after unwrap_or it says

Like with map above, the standard library implementation is a method instead of a free function.


#5

You can’t call free functions using the dot notation. Your example with fn map(option: Option) it can only be called as a free function map(opt).

You could define a trait and implement it for Option to add your methods to it, but that’s a different feature, and it still uses self in the fn definition.

OTOH methods are more flexible, and a method fn map(self,…) can be called using both dot notation and as a free function (Option::map(opt, callback)).


#6

Then the confusion was called by the book. So the definition that is given and the actual example that shows the application of the map function should not be understood together.

Thanks for the help.