PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Sunday, July 10, 2022

[FIXED] why should this be borrowed?

 July 10, 2022     reference, rust     No comments   

Issue

From The Book, listing 13-29:

pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
    contents
        .lines()
        .filter(|line| line.contains(query))
        .collect()
}

After an explanation of the above, the reader is invited, "Feel free to make the same change to use iterator methods in the search_case_insensitive function as well." Don't mind if I do:

pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
    contents
        .lines()
        .filter(|line| line.to_lowercase().contains(query.to_lowercase()))
        .collect()
}

Nope:

error[E0277]: expected a `FnMut<(char,)>` closure, found `String`
   --> src/lib.rs:59:53
    |
59  |         .filter(|line| line.to_lowercase().contains(query.to_lowercase()))
    |                                            -------- ^^^^^^^^^^^^^^^^^^^^ expected an implementor of trait `Pattern<'_>`
    |                                            |
    |                                            required by a bound introduced by this call
    |
    = note: the trait bound `String: Pattern<'_>` is not satisfied
    = note: required because of the requirements on the impl of `Pattern<'_>` for `String`
note: required by a bound in `core::str::<impl str>::contains`
help: consider borrowing here
    |
59  |         .filter(|line| line.to_lowercase().contains(&query.to_lowercase()))
    |                                                     +

Indeed, this compiles and passes the tests from the earlier examples:

pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
    contents
        .lines()
        .filter(|line| line.to_lowercase().contains(&query.to_lowercase()))
        .collect()
}

For that matter, search will compile and pass if query is borrowed:

pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
    contents
        .lines()
        .filter(|line| line.contains(&query))
        .collect()
}

So why must query be borrowed in search_case_insensitive but its being a reference (or not) makes no difference to search?


Solution

The method str::contains() takes as a predicate generic P: Pattern. The Pattern trait is implemented for char, &char, &String, &[char], &str, &&str, [char; N], &[char; N] and F where F: FnMut(char) -> bool. All of those can be passed to contains(). However, it is not implemented for String. So in search(), you pass &str. That's fine. If you borrow it, you pass &&str, which is also fine. But in search_case_insensitive(), if you borrow you pass &String and that's fine, but if you don't, you pass String which does not implement the Pattern trait.



Answered By - Chayim Friedman
Answer Checked By - Terry (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing