Method reference from (NOT to) a local variable

use regex::Regex;
use std::collections::HashMap;

/// Count occurrences of words.
pub fn word_count(words: &str) -> HashMap<String, u32> {
    let word_re = Regex::new(r"\d+|([a-zA-Z]+(?:'??[a-zA-Z]+))").unwrap();

    words
        .split_whitespace()
        .flat_map(|w| word_re.find_iter(w))
        .map(|w| w.as_str().to_lowercase())
        .fold(HashMap::new(), |mut freq, w| {
            *freq.entry(w).or_default() += 1;
            freq
        })
}

flat_map(word_re::find_iter) fails compilation with "use of undeclared crate or module word_re". What is the correct syntax for using a method reference from a local variable?

It's impossible, since "method reference" is not a bare function, but essentially a closure which captures the object it's called on.

That's unexpected, languages like Java can do it just fine. word_re does have an associated method find_iter. That said, I'm just learning, so, I'm going to let it slide as a design limitation.

Languages like Java are fine with creating the closures implicitly, I'd say that's the difference.

3 Likes

Note that, although it doesn't lead to the concision you were looking for, it is possible to call find_iter like this:

Regex::find_iter(&word_re, w)

If you want to read more about this way of calling methods, it is called "Universal Function Call Syntax"

For the special case of a method without any extra parameters, you can use this syntax where you might otherwise use a closure such as str::to_lowercase in this version of part of your code:

    words
        .split_whitespace()
        .flat_map(|w| Regex::find_iter(&word_re, w))
        .map(|w| w.as_str())
        .map(str::to_lowercase)
        .fold(HashMap::new(), |mut freq, w| {
            *freq.entry(w).or_default() += 1;
            freq
        })

Unfortunately, replacing |w| w.as_str() with the analogous regex::Match::as_str does not work, because as_str expects a reference:

12  |         .map(regex::Match::as_str)
    |          --- ^^^^^^^^^^^^^^^^^^^^
    |          |   |
    |          |   expected signature of `fn(regex::Match<'_>) -> _`
    |          |   found signature of `for<'r> fn(&'r regex::Match<'_>) -> _`
    |          required by a bound introduced by this call

Playground Link

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.